title: JNI Attach/Detach thread memory management
body: <p>I have a JNI Callback:</p>
  
  <pre><code>void callback(Data *data, char *callbackName){
      JNIEnv *env;
      jvm-&gt;AttachCurrentThread((void **)&amp;env, NULL);
      /* start useful code*/
  
      /* end useful code */
      jvm-&gt;DetachCurrentThread();
  }
  </code></pre>
  
  <p>When I run it like this (empty useful code), I get a memory leak. If I comment out the whole method, there is no leak. What is the correct way of attaching / detaching threads?</p>
  
  <p>My application processes real-time sound data, so the threads responsible for data processing must be done as soon as possible in order to be ready for another batch. So for these callbacks, I create new threads. There are dozens or even hundreds of them each second, they attach themselves to JVM, call a callback function which repaints a graph, detach and die. Is this a correct way of doing this stuff? How to handle the leaking memory?</p>
  
  <p>EDIT: typo</p>
  
  <p>OK I have created a mimimal code needed:</p>
  
  <pre><code>package test;
  
  public class Start
  {
      public static void main(String[] args) throws InterruptedException{
          System.loadLibrary("Debug/JNITest");
          start();
      }
  
      public static native void start();
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>#include &lt;jni.h&gt;
  #include &lt;Windows.h&gt;
  #include "test_Start.h"
  
  JavaVM *jvm;
  DWORD WINAPI attach(__in  LPVOID lpParameter);
  
  JNIEXPORT void JNICALL Java_test_Start_start(JNIEnv *env, jclass){
      env-&gt;GetJavaVM(&amp;jvm);
      while(true){
          CreateThread(NULL, 0, &amp;(attach), NULL, 0, NULL);
          Sleep(10);
      }
  }
  
  
  DWORD WINAPI attach(__in  LPVOID lpParameter){
      JNIEnv *env;
      jvm-&gt;AttachCurrentThread((void **)&amp;env, NULL);
      jvm-&gt;DetachCurrentThread();
      return 0;
  }
  </code></pre>
  
  <p>and when I run the VisualJM profiler, I get the usual sawtooth pattern, no leak there. Heap usage peaked at around 5MB. However, observing the process explorer indeed shows some weird behaviour: memory is slowly rising and rising, 4K a second for a minute or so and then suddenly all this allocated memory drops. These drops do not correspond with garbage collection (they occur less often and deallocate less memory than those saw-teeth in the profiler).</p>
  
  <p>So my best bet is that it is some OS behaviour handling tens of thousands milisecond-lived threads. Does some guru have an explanation for this?</p>