Faster alternative to get tags for objects than JVMTI GetTag
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));
}
- 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
|
show 2 more comments
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));
}
- 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
What aboutIdentityHashMap
? 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 theoop
and use it as key directly? So the same wayget_tag
is 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 nakedoop
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 thejobject
is only casted tooop*
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 anoop
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, seeJvmtiTagMap::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
|
show 2 more comments
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));
}
- 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
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));
}
- 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
java performance jvm jvm-hotspot jvmti
edited Nov 14 '18 at 23:53
Haasip Satang
asked Nov 14 '18 at 23:10
Haasip SatangHaasip Satang
232212
232212
What aboutIdentityHashMap
? 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 theoop
and use it as key directly? So the same wayget_tag
is 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 nakedoop
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 thejobject
is only casted tooop*
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 anoop
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, seeJvmtiTagMap::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
|
show 2 more comments
What aboutIdentityHashMap
? 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 theoop
and use it as key directly? So the same wayget_tag
is 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 nakedoop
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 thejobject
is only casted tooop*
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 anoop
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, seeJvmtiTagMap::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_tag
is 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_tag
is 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
jobject
is 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
jobject
is 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
|
show 2 more comments
1 Answer
1
active
oldest
votes
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 wayget_tag
is 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
jobject
is only casted tooop*
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 anoop
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