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.

alan.batemana at 2007-7-10 0:43:17 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...
# 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 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...
# 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 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...
# 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.

alan.batemana at 2007-7-10 0:43:17 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...
# 5
How can I test that my program is working when one class has unloaded during the runing?Anyway What does it means that unload a class(can it occur when not enough memory and there aren't any references to this class?)
pet_a at 2007-7-10 0:43:17 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...
# 6
I have an other question. Can I use the jmethodID to identify the methods? I mean I write out the jmethodID (4byte memory address - this is a pointer to struct _jmethodID) like an identifier.
pet_a at 2007-7-10 0:43:17 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...