6 Replies Latest reply on Sep 12, 2009 2:27 AM by 843810

    jvmtiGetThreadInfo deallocation problem

      Hi there,

      Can anybody help me understand why the following code leaks memory (like 40MB/sec)?

      Assuming jmvti and currentThread are defined and are of the correct types in:
      jvmtiThreadInfo info;
      (void)memset(&info, 0, sizeof(info));
      for (int i = 0; i<10000; i++) {
        for (int j = 0; j<10000; j++) {     
            jvmti->GetThreadInfo(currentThread, &info);
            jvmti->Deallocate((unsigned char *)(info.name));      
      and that the name of the thread is acquired correctly, why does this leak?

      According to [http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#GetThreadInfo] all I have to do is deallocate the name array as I do. Keep in mind that if I do not cast the info.name to
      unsigned char *
      , the compiler complains about an invalid conversion from
      char * to unsigned char *
      Thank you for your time in advance,

      Edited by: Johnny83 on Sep 10, 2009 7:02 AM
        • 1. Re: jvmtiGetThreadInfo deallocation problem
          The spec for JVM/TI GetThreadInfo() also mentions:

          The object returned in the field thread_group of jvmtiThreadInfo is a
          JNI local reference and must be managed. The object returned in
          the field context_class_loader of jvmtiThreadInfo is a JNI local
          reference and must be managed.

          Since you are calling GetThreadInfo() in a tight loop, you are allocating
          two JNI local references per iteration. Those will need to be freed so
          you should follow the link to the JNI spec. I don't know if this will account
          for all of your memory "leak", but it's a start.
          • 2. Re: jvmtiGetThreadInfo deallocation problem
            Yeap, that was it. Fixing the code to
            jvmti->GetThreadInfo(myThread, &info);
            jvmti->Deallocate((unsigned char *)(info.name));
            stopped the leaking. Thank you indeed for your help, I was sidetracked by numerous sources I found on the Internet, that never managed these objects (probably because they used a previous version of JVMTI that did not contain them in the corresponding struct).

            Best Regards,
            • 3. Re: jvmtiGetThreadInfo deallocation problem
              Just a clarification: those fields have always been present in the
              jvmtiThreadInfo structure.

              Also, you used JNI DeleteWeakGlobalRef() and you probably should
              have used JNI DeleteLocalRef().

              The examples you found on the web might have been simple calls to
              GetThreadInfo() that returned from the native code right away. In that
              case, explicit management of the local JNI references is not needed.

              See the following link:


              for the gory details.
              • 4. Re: jvmtiGetThreadInfo deallocation problem
                Thanks for the clarification, though I do not quite get when this management should take place explicitly by the programmer and when it is automatically done (your your link is broken and I couldn't make more out of it - could you plz post the correct one - searching for variations of it, I ended up in a free dating services site :)).

                Meanwhile, regarding the weak references thing, using DeleteGlobalRef, as I initially did, resulted in the -Xcheck:jni complaining:

                FATAL ERROR in native method: Invalid global JNI handle passed to DeleteGlobalRef

                I really do not want to take any more of your time - just pointing to the link you mention is more than enough

                Thanks again,
                • 5. Re: jvmtiGetThreadInfo deallocation problem
                  Sorry, that was an internal link. Here's the public link:


                  It looks like the JNI spec link on that page is also broken. Try this one:

                  • 6. Re: jvmtiGetThreadInfo deallocation problem
                    The broken JNI spec link on the following page is now fixed: