title: Memory leaks using JNI: are we releasing objects property?
body: <p><strong>IMPORTANT NOTE:</strong> This snippet of code is not a <code>native</code> function called from Java. Our process is written in C++, we instantiate a Java VM, and we call Java functions from C++, but never the other way around: Java methods never calls native functions, but native functions instantiate Java objects and call Java functions on them.</p>
  <p>We are doing something like this:</p>
  <pre class="lang-cpp prettyprint-override"><code>void some_fun()
  {
      // env is a JNIEnv*, cls (and cls2) a jclass, and init (and mid) a jmethodID
      jobject obj = env-&gt;NewObject(cls, init);
      fill_obj(obj, cpp_data);
      env-&gt;callStaticVoidMethod(cls2, mid, obj);
      // env-&gt;DeleteLocalRef(obj); // Added out of desperation.
  }
  </code></pre>
  <p>Where <code>fill_obj</code> depends on the kind of <code>cpp_data</code> that must be set as fields of <code>obj</code>. For example, if the Java class <code>cls</code> contains an <code>ArrayList</code>, <code>cpp_data</code> will contain, for example, a <code>std::vector</code>. So the <code>fill_obj</code> overload will look like this:</p>
  <pre class="lang-cpp prettyprint-override"><code>void fill_obj(jobject obj, SomeType const&amp; cpp_data)
  {
     std::vector&lt;SomeSubType&gt; const&amp; v = cpp_data.inner_data;
     jobject list_obj = env-&gt;NewObject(array_list_class_global_ref, its_init_method);
  
     for (auto it = v.begin(); it != v.end(); ++it) {
        jobject child_obj = env-&gt;NewObject(SomeSubType_class_global_ref, its_init_method);
        fill_obj(child_obj , *it);
        env-&gt;CallBooleanMethod(list_obj, add_method, child_obj);
     }
  
     env-&gt;SetObjectField(obj, field_id, list_obj);
  }
  </code></pre>
  <p>According to our understanding on the JNI docs, that code should not have any memory leaks since local objects are destroyed when the native method ends. So, when the first <code>fill_obj</code> ends, at C++ side there's no more references to <code>list_obj</code> or any of its childs, and when <code>some_fun</code> ends, any reference of <code>obj</code> at C++ side is gone as well.</p>
  <p>My understanding is that <code>jobject</code> contains some sort of reference counter and when that reference counter reachs 0, then there's no more references to the Java object at C++ side. If there's no more references to the object at Java side either, then the Java's garbage collector is free to release the resources occupied by the object.</p>
  <p>We have a method that, when called, creates thousand of those objects, and each time that method is called, the memory that the process occupies in RAM (the resident memory) grows by more than 200 MiB, and that memory is never released.</p>
  <p>We have added an explicit call to <code>DeleteLocalRef</code> but the result is the same.</p>
  <p>What is going on? Are we doing something wrong?</p>