gpt4 book ai didi

java - 使用 JNI 从 C 调用 java 代码时发生内存泄漏

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:02:20 26 4
gpt4 key购买 nike

我有一个 C 程序,它使用 JNI 在 java 存储中存储一些对象。 (在有人问之前,这里需要使用 java store,我必须用 C 编写一个客户端,它能够从这个 store 添加和检索对象)。

我编写了程序并尝试添加 100000 个大小为 1KB 的对象。但是在仅添加 50000 个对象后,我收到“内存不足”消息(请注意,每当我无法使用 NewStringUTF 和 NewByteArray 函数分配新的字符串或字节数组时,我都会打印这些“内存不足”消息)。那时我的应用程序只使用了 80MB 的内存。我不明白为什么这些方法返回 NULL。有什么我想念的吗。

此外,即使我正在释放为 java 创建的字节数组和字符串,内存也会继续增加。

这是源代码。

    void create_jvm(void)
{
JavaVMInitArgs vm_args;
JavaVMOption vm_options;

vm_options.optionString = "-Djava.class.path=c:\\Store";
vm_args.version = JNI_VERSION_1_4;
vm_args.nOptions = 1;
vm_args.options = &vm_options;
vm_args.ignoreUnrecognized = 0;

JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

if(env != null)
{
j_store = (*env)->FindClass(env, "com/store");
if(j_store == null)
{
printf("unable to find class. class name: JStore");
}
}
}

void add(char* key, char* value, int length)
{
jstring j_key = (*env)->NewStringUTF(env, key);
jbyteArray j_value = (*env)->NewByteArray(env, length);

(*env)->SetByteArrayRegion(env, j_value, 0, length, (jbyte *)value);
ret = (*env)->CallStaticBooleanMethod(env, j_store, method_id, j_key, j_value);

if(j_value != null)
{
(*env)->ReleaseByteArrayElements(env, j_value, (jbyte *)value, 0);
}
if(j_key != null)
{
(*env)->ReleaseStringUTFChars(env, j_key, key);
}
}

java端接收byte[]中的数据并将其存储在哈希表中。问题是每次代码运行时,内存只会累加而永远不会释放。我尝试添加 1 MB 对象并对其进行调试。

当我调用 NewByteArray 时,进程内存增加了 1MB。但是调用 CallStaticBooleanMethod 时进程内存增加了 4MB。调用 ReleaseByteArrayElements 根本不会释放任何内存。

如果我在此之后添加另一个 1MB 对象,那么当我调用 NewByteArray 时进程内存保持不变,当我调用 CallStaticBooleanMethod 时它增加 1MB 但当我尝试释放字节数组时它保持不变。

最佳答案

当您调用 New... 函数时,您会创建一个“本地引用” - 对本地堆栈框架中此对象的引用。这可以防止 Java VM 在您仍然需要该对象时对其进行 GC。如果您正在实现一些 native 方法,这很好 - 它的本地框架仅为方法调用持续时间创建。但是,当您从本地 java 附加线程创建对象时,它会绑定(bind)到此线程堆栈帧,该堆栈帧只会被此线程销毁。

因此,当您处理完某个对象后,您可以调用 DeleteLocalRef() 来告诉您不再需要它。或者,您可以用一对 P​​ushLocalFrame()/PopLocalFrame() 包围整个 add() 函数,以在其持续时间内创建一个单独的本地框架。

关于java - 使用 JNI 从 C 调用 java 代码时发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1340938/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com