title: Memory leak in SWIG polymorphism across C++ and Java using directors
body: <p>I have a C++ program to receive binary data from network. After data is received, it will callback the data as a byte array from C++ to a Java client. I use the director feature in SWIG to easily achieve cross language polymorphism across C++ and Java for callback. Here's <a href="http://www.swig.org/Doc2.0/Java.html#Java_directors" rel="nofollow">a link</a>.</p>
  
  <p>But I found there is no typemaps in SWIG from char* in C++ to byte[] in Java. So, I added a patch to the virous.i. Here's <a href="http://sourceforge.net/tracker/?func=detail&amp;aid=3421791&amp;group_id=1645&amp;atid=301645" rel="nofollow">a link</a>.</p>
  
  <pre><code>/*Director specific typemaps*/
  %typemap(directorin, descriptor="[B") char *BYTE {
      jbyteArray jb = (jenv)-&gt;NewByteArray(strlen(BYTE));
     (jenv)-&gt;SetByteArrayRegion(jb, 0, strlen(BYTE), (jbyte*)BYTE);
      $input = jb;
  }
  %typemap(directorout) char *BYTE {
  $1 = 0;
  if($input){
          $result = (char *) jenv-&gt;GetByteArrayElements($input, 0); 
          if(!$1) 
              return $null;
          jenv-&gt;ReleaseByteArrayElements($input, $result, 0);
      }
  }
  %typemap(javadirectorin) char *BYTE "$jniinput"
  %typemap(javadirectorout) char *BYTE "$javacall"
  </code></pre>
  
  <p>For example. I have a class in C++ called A:</p>
  
  <pre><code>class A{
  public:
         virtual void onDataReceived(const char* BYTE, const size_t len) {}
  };
  </code></pre>
  
  <p>Then in Java code I have another class B to extend A:</p>
  
  <pre><code>class B extends A {
      @Override
      public void onDataReceived(byte[] data, long len) {
         //handling the data.
      }
  }
  </code></pre>
  
  <p>I can receive the byte array in Java code, but it seems it is never garbage collected by JVM. The onDataReceived method in SWIG generated wrapper file is like this:</p>
  
  <pre><code>void SwigDirector_A::onDataReceived(char const *BYTE, size_t const len) {
    JNIEnvWrapper swigjnienv(this);
    JNIEnv * jenv = swigjnienv.getJNIEnv();
    jobject swigjobj = (jobject) NULL;
    jbyteArray jBYTE = 0;
    jlong jlen;
  
    if (!swig_override[3]) {
      A::onDataReceived(BYTE,len);
      return;
    }
    swigjobj = swig_get_self(jenv);
    if (swigjobj &amp;&amp; jenv-&gt;IsSameObject(swigjobj, NULL) == JNI_FALSE) {
      {
        jbyteArray jb = (jenv)-&gt;NewByteArray(strlen(BYTE));
        (jenv)-&gt;SetByteArrayRegion(jb, 0, strlen(BYTE), (jbyte*)BYTE);
        jBYTE = jb;
      }
      jlen = (jlong) len;
      jenv-&gt;CallStaticVoidMethod(Swig::jclass_DataTransferJNI, Swig::director_methids[3], swigjobj, jBYTE, jlen);
      if (jenv-&gt;ExceptionCheck() == JNI_TRUE) return;
    } else {
      SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object");
    }
    if (swigjobj) jenv-&gt;DeleteLocalRef(swigjobj);
  }
  </code></pre>
  
  <p>In my C++ code, I will delete the data in the receive buffer after the callback is done. But I checked from Java VisualVM that the memory used by java client process is not GC-ed after a long time. Thanks advance for any help!</p>
  
  <p>PS. The data is quite large, it is around 32KB.</p>