jmethodID remains the same during the running(jvmti + jni)
Hi all!
I have a question. I'd like to store in a map the jmethodID that I get from the methodentry jvmti event. And when I get another methodentry event I'd like to decide if the recieved jmethodID is new or I saw that before. But I don't know that jmethodID that I recieve remains the same during the running of the java application.
Perhaps the gc frees some object and put others somewhere else in the memory. In this case will my stored jmethodID show the real method or not?
[502 byte] By [
pet_a] at [2007-11-26 20:19:22]

# 1
Yes, you can use a jmethodID for this purpose. One thing to remember is that the jmethodID becomes invalid once the class is unloaded. One suggestion is to tag the class and enable the ObjectFree event (which is only called for tagged objects). In the callback for this event you can purge your map or data structures of information about this class and its methods.
# 2
How can I compare methodIDs. Just simply if (method1 == method2) ?
How can I unload a class? (How can I make the vm to change one method's id?)
I tried to this:
class A {
int foo = 0;
public void print(String str) {
System.out.println(str);
}
protected void finalize() {
B.loop = false;
}
}
class B {
public static boolean loop = true;
}
public class Test {
public static void main(String[] args) {
A obj = new A();
obj.print("before");
obj.print("before");
obj = null;
while (B.loop) {
A o = new A();
o.print("loop");
System.gc();
}
A obj2 = new A();
obj2.print("after");
obj2.print("after");
}
}
The result:
GC has started and finished(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, JVMTI_EVENT_GARBAGE_COLLECTION_START) but freeobject event hasn't occured(I called SetTag(class, tag) in the methodentry event).
pet_a at 2007-7-10 0:43:17 >

# 3
This is the same code(just for better visibility;):
class A {
int foo = 0;
public void print(String str) {
System.out.println(str);
}
protected void finalize() {
B.loop = false;
}
}
class B {
public static boolean loop = true;
}
public class Test {
public static void main(String[] args) {
A obj = new A();
obj.print("before");
obj.print("before");
obj = null;
while (B.loop) {
A o = new A();
o.print("loop");
System.gc();
}
A obj2 = new A();
obj2.print("after");
obj2.print("after");
}
}
pet_a at 2007-7-10 0:43:17 >

# 4
Yes, you can compare jmethodIDs using ==. There is no way to explicitly unload a class. If you run with -verbose:class then you will get trace messages emitted to standard output when classes are loaded and unloaded. In your example, the objects are likely to have been GC'ed but no classes will be unloaded.