Faster alternative to get tags for objects than JVMTI GetTag












0















When profiling with async profiler and gperftools I noticed that jvmti->GetTag shows up quite a lot in the results for my agent. When I checked how it is implemented I found the following in the source of jvmitTagMap.cpp:



jlong JvmtiTagMap::get_tag(jobject object) {
MutexLocker ml(lock());

// resolve the object
oop o = JNIHandles::resolve_non_null(object);

// for Classes get the tag from the klassOop
return tag_for(this, klassOop_if_java_lang_Class(o));
}



  1. Although my test only had one thread that was really under load it seems that this will scale even less once I add more threads and make heavy use of GetTag.


I wanted to use the tag to assign an id to certain objects and use it in my jvmti agent. Any ideas for a faster way accomplish that? Messing with the object header obvioulsy is not an option (to my knowledge).



NOTE: Most things should be done on C side as I do not want my Java agent to interfer with the application in any way. By interfer I even mean things like changing internal state of some central objects / classes (like java.lang.StringCoding for example), or leading to some classes being loaded, etc



GetTag is already used heavily throughout the current JVMTI agent, so I am looking for a faster way to get the tag or implement my own mechanism while staying on C side.










share|improve this question

























  • What about IdentityHashMap? The question is too broad actually. This depends on why you need ID at all and how you use it.

    – apangin
    Nov 14 '18 at 23:24











  • Good point, updated the question. In short: I need the id on C side without messing with whatever happens in Java. Actually now that I think about it...since I only need a unique identifier per object that does not change during life time shouldn't I be able to get the oop and use it as key directly? So the same way get_tagis doing it.

    – Haasip Satang
    Nov 15 '18 at 0:05











  • When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead. I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.

    – apangin
    Nov 15 '18 at 21:54











  • I understand it is not public API but nevertheless would like to know what is going on under the hood. From what I saw today it looked like the jobjectis only casted to oop* which then is dereferenced and later casted to ùnsigned int` to be used as hash in the tag map. But I must be missing something here. How can the oop be the key in a map when the object keeps moving around memory? If I understood correctly an oop points to an object header, but the object can be moved around by GC. I don't think that the keys in the maps are updated all the time an object is moved, right?

    – Haasip Satang
    Nov 16 '18 at 0:26






  • 1





    JVM knows about JvmtiTagMap and updates it whenever the objects are moved, see JvmtiTagMap::do_weak_oops. When JVM deals with raw pointers to Java heap, i.e. oops, it either ensures that no GC happens in between, or wraps oops into handles. jobject is an example of such oop handle.

    – apangin
    Nov 16 '18 at 12:33
















0















When profiling with async profiler and gperftools I noticed that jvmti->GetTag shows up quite a lot in the results for my agent. When I checked how it is implemented I found the following in the source of jvmitTagMap.cpp:



jlong JvmtiTagMap::get_tag(jobject object) {
MutexLocker ml(lock());

// resolve the object
oop o = JNIHandles::resolve_non_null(object);

// for Classes get the tag from the klassOop
return tag_for(this, klassOop_if_java_lang_Class(o));
}



  1. Although my test only had one thread that was really under load it seems that this will scale even less once I add more threads and make heavy use of GetTag.


I wanted to use the tag to assign an id to certain objects and use it in my jvmti agent. Any ideas for a faster way accomplish that? Messing with the object header obvioulsy is not an option (to my knowledge).



NOTE: Most things should be done on C side as I do not want my Java agent to interfer with the application in any way. By interfer I even mean things like changing internal state of some central objects / classes (like java.lang.StringCoding for example), or leading to some classes being loaded, etc



GetTag is already used heavily throughout the current JVMTI agent, so I am looking for a faster way to get the tag or implement my own mechanism while staying on C side.










share|improve this question

























  • What about IdentityHashMap? The question is too broad actually. This depends on why you need ID at all and how you use it.

    – apangin
    Nov 14 '18 at 23:24











  • Good point, updated the question. In short: I need the id on C side without messing with whatever happens in Java. Actually now that I think about it...since I only need a unique identifier per object that does not change during life time shouldn't I be able to get the oop and use it as key directly? So the same way get_tagis doing it.

    – Haasip Satang
    Nov 15 '18 at 0:05











  • When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead. I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.

    – apangin
    Nov 15 '18 at 21:54











  • I understand it is not public API but nevertheless would like to know what is going on under the hood. From what I saw today it looked like the jobjectis only casted to oop* which then is dereferenced and later casted to ùnsigned int` to be used as hash in the tag map. But I must be missing something here. How can the oop be the key in a map when the object keeps moving around memory? If I understood correctly an oop points to an object header, but the object can be moved around by GC. I don't think that the keys in the maps are updated all the time an object is moved, right?

    – Haasip Satang
    Nov 16 '18 at 0:26






  • 1





    JVM knows about JvmtiTagMap and updates it whenever the objects are moved, see JvmtiTagMap::do_weak_oops. When JVM deals with raw pointers to Java heap, i.e. oops, it either ensures that no GC happens in between, or wraps oops into handles. jobject is an example of such oop handle.

    – apangin
    Nov 16 '18 at 12:33














0












0








0








When profiling with async profiler and gperftools I noticed that jvmti->GetTag shows up quite a lot in the results for my agent. When I checked how it is implemented I found the following in the source of jvmitTagMap.cpp:



jlong JvmtiTagMap::get_tag(jobject object) {
MutexLocker ml(lock());

// resolve the object
oop o = JNIHandles::resolve_non_null(object);

// for Classes get the tag from the klassOop
return tag_for(this, klassOop_if_java_lang_Class(o));
}



  1. Although my test only had one thread that was really under load it seems that this will scale even less once I add more threads and make heavy use of GetTag.


I wanted to use the tag to assign an id to certain objects and use it in my jvmti agent. Any ideas for a faster way accomplish that? Messing with the object header obvioulsy is not an option (to my knowledge).



NOTE: Most things should be done on C side as I do not want my Java agent to interfer with the application in any way. By interfer I even mean things like changing internal state of some central objects / classes (like java.lang.StringCoding for example), or leading to some classes being loaded, etc



GetTag is already used heavily throughout the current JVMTI agent, so I am looking for a faster way to get the tag or implement my own mechanism while staying on C side.










share|improve this question
















When profiling with async profiler and gperftools I noticed that jvmti->GetTag shows up quite a lot in the results for my agent. When I checked how it is implemented I found the following in the source of jvmitTagMap.cpp:



jlong JvmtiTagMap::get_tag(jobject object) {
MutexLocker ml(lock());

// resolve the object
oop o = JNIHandles::resolve_non_null(object);

// for Classes get the tag from the klassOop
return tag_for(this, klassOop_if_java_lang_Class(o));
}



  1. Although my test only had one thread that was really under load it seems that this will scale even less once I add more threads and make heavy use of GetTag.


I wanted to use the tag to assign an id to certain objects and use it in my jvmti agent. Any ideas for a faster way accomplish that? Messing with the object header obvioulsy is not an option (to my knowledge).



NOTE: Most things should be done on C side as I do not want my Java agent to interfer with the application in any way. By interfer I even mean things like changing internal state of some central objects / classes (like java.lang.StringCoding for example), or leading to some classes being loaded, etc



GetTag is already used heavily throughout the current JVMTI agent, so I am looking for a faster way to get the tag or implement my own mechanism while staying on C side.







java performance jvm jvm-hotspot jvmti






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 23:53







Haasip Satang

















asked Nov 14 '18 at 23:10









Haasip SatangHaasip Satang

232212




232212













  • What about IdentityHashMap? The question is too broad actually. This depends on why you need ID at all and how you use it.

    – apangin
    Nov 14 '18 at 23:24











  • Good point, updated the question. In short: I need the id on C side without messing with whatever happens in Java. Actually now that I think about it...since I only need a unique identifier per object that does not change during life time shouldn't I be able to get the oop and use it as key directly? So the same way get_tagis doing it.

    – Haasip Satang
    Nov 15 '18 at 0:05











  • When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead. I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.

    – apangin
    Nov 15 '18 at 21:54











  • I understand it is not public API but nevertheless would like to know what is going on under the hood. From what I saw today it looked like the jobjectis only casted to oop* which then is dereferenced and later casted to ùnsigned int` to be used as hash in the tag map. But I must be missing something here. How can the oop be the key in a map when the object keeps moving around memory? If I understood correctly an oop points to an object header, but the object can be moved around by GC. I don't think that the keys in the maps are updated all the time an object is moved, right?

    – Haasip Satang
    Nov 16 '18 at 0:26






  • 1





    JVM knows about JvmtiTagMap and updates it whenever the objects are moved, see JvmtiTagMap::do_weak_oops. When JVM deals with raw pointers to Java heap, i.e. oops, it either ensures that no GC happens in between, or wraps oops into handles. jobject is an example of such oop handle.

    – apangin
    Nov 16 '18 at 12:33



















  • What about IdentityHashMap? The question is too broad actually. This depends on why you need ID at all and how you use it.

    – apangin
    Nov 14 '18 at 23:24











  • Good point, updated the question. In short: I need the id on C side without messing with whatever happens in Java. Actually now that I think about it...since I only need a unique identifier per object that does not change during life time shouldn't I be able to get the oop and use it as key directly? So the same way get_tagis doing it.

    – Haasip Satang
    Nov 15 '18 at 0:05











  • When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead. I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.

    – apangin
    Nov 15 '18 at 21:54











  • I understand it is not public API but nevertheless would like to know what is going on under the hood. From what I saw today it looked like the jobjectis only casted to oop* which then is dereferenced and later casted to ùnsigned int` to be used as hash in the tag map. But I must be missing something here. How can the oop be the key in a map when the object keeps moving around memory? If I understood correctly an oop points to an object header, but the object can be moved around by GC. I don't think that the keys in the maps are updated all the time an object is moved, right?

    – Haasip Satang
    Nov 16 '18 at 0:26






  • 1





    JVM knows about JvmtiTagMap and updates it whenever the objects are moved, see JvmtiTagMap::do_weak_oops. When JVM deals with raw pointers to Java heap, i.e. oops, it either ensures that no GC happens in between, or wraps oops into handles. jobject is an example of such oop handle.

    – apangin
    Nov 16 '18 at 12:33

















What about IdentityHashMap? The question is too broad actually. This depends on why you need ID at all and how you use it.

– apangin
Nov 14 '18 at 23:24





What about IdentityHashMap? The question is too broad actually. This depends on why you need ID at all and how you use it.

– apangin
Nov 14 '18 at 23:24













Good point, updated the question. In short: I need the id on C side without messing with whatever happens in Java. Actually now that I think about it...since I only need a unique identifier per object that does not change during life time shouldn't I be able to get the oop and use it as key directly? So the same way get_tagis doing it.

– Haasip Satang
Nov 15 '18 at 0:05





Good point, updated the question. In short: I need the id on C side without messing with whatever happens in Java. Actually now that I think about it...since I only need a unique identifier per object that does not change during life time shouldn't I be able to get the oop and use it as key directly? So the same way get_tagis doing it.

– Haasip Satang
Nov 15 '18 at 0:05













When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead. I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.

– apangin
Nov 15 '18 at 21:54





When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead. I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.

– apangin
Nov 15 '18 at 21:54













I understand it is not public API but nevertheless would like to know what is going on under the hood. From what I saw today it looked like the jobjectis only casted to oop* which then is dereferenced and later casted to ùnsigned int` to be used as hash in the tag map. But I must be missing something here. How can the oop be the key in a map when the object keeps moving around memory? If I understood correctly an oop points to an object header, but the object can be moved around by GC. I don't think that the keys in the maps are updated all the time an object is moved, right?

– Haasip Satang
Nov 16 '18 at 0:26





I understand it is not public API but nevertheless would like to know what is going on under the hood. From what I saw today it looked like the jobjectis only casted to oop* which then is dereferenced and later casted to ùnsigned int` to be used as hash in the tag map. But I must be missing something here. How can the oop be the key in a map when the object keeps moving around memory? If I understood correctly an oop points to an object header, but the object can be moved around by GC. I don't think that the keys in the maps are updated all the time an object is moved, right?

– Haasip Satang
Nov 16 '18 at 0:26




1




1





JVM knows about JvmtiTagMap and updates it whenever the objects are moved, see JvmtiTagMap::do_weak_oops. When JVM deals with raw pointers to Java heap, i.e. oops, it either ensures that no GC happens in between, or wraps oops into handles. jobject is an example of such oop handle.

– apangin
Nov 16 '18 at 12:33





JVM knows about JvmtiTagMap and updates it whenever the objects are moved, see JvmtiTagMap::do_weak_oops. When JVM deals with raw pointers to Java heap, i.e. oops, it either ensures that no GC happens in between, or wraps oops into handles. jobject is an example of such oop handle.

– apangin
Nov 16 '18 at 12:33












1 Answer
1






active

oldest

votes


















0














When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead.



I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.



JVM, however, can work with oops and even use the object address as a key in JvmtiTagMap as long as it updates the corresponding oops whenever the objects are moved. And HotSpot JVM indeed does this, see JvmtiTagMap::do_weak_oops.






share|improve this answer
























  • Thinking more about it, it makes sense that the JVM knows the map. In the end there is also cleanup needed once an object got gc'ed. Thanks a lot.

    – Haasip Satang
    Nov 16 '18 at 15:01











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310123%2ffaster-alternative-to-get-tags-for-objects-than-jvmti-gettag%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead.



I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.



JVM, however, can work with oops and even use the object address as a key in JvmtiTagMap as long as it updates the corresponding oops whenever the objects are moved. And HotSpot JVM indeed does this, see JvmtiTagMap::do_weak_oops.






share|improve this answer
























  • Thinking more about it, it makes sense that the JVM knows the map. In the end there is also cleanup needed once an object got gc'ed. Thanks a lot.

    – Haasip Satang
    Nov 16 '18 at 15:01
















0














When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead.



I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.



JVM, however, can work with oops and even use the object address as a key in JvmtiTagMap as long as it updates the corresponding oops whenever the objects are moved. And HotSpot JVM indeed does this, see JvmtiTagMap::do_weak_oops.






share|improve this answer
























  • Thinking more about it, it makes sense that the JVM knows the map. In the end there is also cleanup needed once an object got gc'ed. Thanks a lot.

    – Haasip Satang
    Nov 16 '18 at 15:01














0












0








0







When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead.



I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.



JVM, however, can work with oops and even use the object address as a key in JvmtiTagMap as long as it updates the corresponding oops whenever the objects are moved. And HotSpot JVM indeed does this, see JvmtiTagMap::do_weak_oops.






share|improve this answer













When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead.



I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.



JVM, however, can work with oops and even use the object address as a key in JvmtiTagMap as long as it updates the corresponding oops whenever the objects are moved. And HotSpot JVM indeed does this, see JvmtiTagMap::do_weak_oops.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 16 '18 at 14:12









apanginapangin

51.5k8100130




51.5k8100130













  • Thinking more about it, it makes sense that the JVM knows the map. In the end there is also cleanup needed once an object got gc'ed. Thanks a lot.

    – Haasip Satang
    Nov 16 '18 at 15:01



















  • Thinking more about it, it makes sense that the JVM knows the map. In the end there is also cleanup needed once an object got gc'ed. Thanks a lot.

    – Haasip Satang
    Nov 16 '18 at 15:01

















Thinking more about it, it makes sense that the JVM knows the map. In the end there is also cleanup needed once an object got gc'ed. Thanks a lot.

– Haasip Satang
Nov 16 '18 at 15:01





Thinking more about it, it makes sense that the JVM knows the map. In the end there is also cleanup needed once an object got gc'ed. Thanks a lot.

– Haasip Satang
Nov 16 '18 at 15:01




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310123%2ffaster-alternative-to-get-tags-for-objects-than-jvmti-gettag%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python