JNI native memory leak - release array elements (#10981)

Summary:
Closes https://github.com/facebook/rocksdb/issues/10980

Reproduced as per the suggestion in the ticket, and `$ jcmd <PID> VM.native_memory | grep Internal` reports that we are no longer leaking internal memory with the suggested fix.

I did the repro in `MultiGetTest.java` which I have optimized imports on. It did not seem helpful to leave the test code around as it would be onerous to build a memory leak reproducer, and regression seems a remote possibility.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/10981

Reviewed By: riversand963

Differential Revision: D41498748

Pulled By: ajkr

fbshipit-source-id: 8c6dd0d608172879c8bda479c7c9c05c12d34e70
This commit is contained in:
Alan Paxton 2022-12-14 10:49:32 -08:00 committed by Facebook GitHub Bot
parent c93ba7db5d
commit 6a8920f988
2 changed files with 14 additions and 0 deletions

View File

@ -1836,6 +1836,10 @@ inline bool keys_from_bytebuffers(JNIEnv* env,
jobject jkey = env->GetObjectArrayElement(jkeys, i);
if (env->ExceptionCheck()) {
// exception thrown: ArrayIndexOutOfBoundsException
// cleanup jkey_off and jkey_len
env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
return false;
}
char* key = reinterpret_cast<char*>(env->GetDirectBufferAddress(jkey));
@ -1844,6 +1848,11 @@ inline bool keys_from_bytebuffers(JNIEnv* env,
env->DeleteLocalRef(jkey);
}
// cleanup jkey_off and jkey_len
env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
return true;
}

View File

@ -11,12 +11,17 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.rocksdb.util.TestUtil;
public class MultiGetTest {
@ClassRule
public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE =
new RocksNativeLibraryResource();
@Rule public TemporaryFolder dbFolder = new TemporaryFolder();
@Test