ByteBuffer keinen Arbeitsspeicher freigibt

Auf Android, eine direkte ByteBuffer nicht immer scheinen lassen seine Erinnerung, auch nicht beim aufrufen von System.gc().

Beispiel: tut

Log.v("?", Long.toString(Debug.getNativeHeapAllocatedSize()));
ByteBuffer buffer = allocateDirect(LARGE_NUMBER);
buffer=null;
System.gc();
Log.v("?", Long.toString(Debug.getNativeHeapAllocatedSize()));

gibt zwei zahlen in der log, die zweite wird mindestens GROSSE_ZAHL größer als der erste.

Wie kann ich loswerden dieser Speicherverlust?


Hinzugefügt:

Folgenden der Vorschlag von Gregory zu handhaben alloc/frei auf der C++ - Seite habe ich dann definiert

JNIEXPORT jobject JNICALL Java_com_foo_bar_allocNative(JNIEnv* env, jlong size)
    {
    void* buffer = malloc(size);
    jobject directBuffer = env->NewDirectByteBuffer(buffer, size);
    jobject globalRef = env->NewGlobalRef(directBuffer);
    return globalRef;
    }

JNIEXPORT void JNICALL Java_com_foo_bar_freeNative(JNIEnv* env, jobject globalRef)
    {
    void *buffer = env->GetDirectBufferAddress(globalRef);
    free(buffer);
    env->DeleteGlobalRef(globalRef);
    }

Ich bekomme dann meine ByteBuffer auf der JAVA-Seite mit

ByteBuffer myBuf = allocNative(LARGE_NUMBER);

und kostenlos mit

freeNative(myBuf);

Leider, während es nicht zuordnen in Ordnung, es a) noch immer hält der Speicher nach Debug.getNativeHeapAllocatedSize() und b) zu einem Fehler führt

W/dalvikvm(26733): JNI: DeleteGlobalRef(0x462b05a0) failed to find entry (valid=1)

Jetzt bin ich gründlich verwirrt, ich dachte, dass ich das zumindest verstanden die C++ - Seite der Dinge... Warum ist free() nicht zurückgegeben Speicher? Und was mache ich falsch mit der DeleteGlobalRef()?

  • allocateDirect Speicher zuweist, die garantiert nicht von der garbage Collection freigegeben.
  • Das ist in Ordnung, aber kann ich frei von der hand, irgendwie? Scheint dumm zu Funktionen, Speicher aber nicht in der Lage sein zu tun ist, die inverse. Ich bin zufrieden mit der Freigabe von JNI, wenn das ist eine option.
  • Jon > allocateDirect Speicher zuweist, dass ist garantiert verlegt durch den garbage collector. Aber sobald die ByteBuffer wird gesammelt, der native Speicher zurückgefordert.
  • siehe meine bearbeitete Antwort über NewGlobalRef und DeleteGlobalRef
  • so? wo sind Sie mit diesem?
  • mögliche Duplikate von Wenn System.gc() alles tun

Schreibe einen Kommentar