ata*_*ata 7 c java java-native-interface memory-leaks
我有一个C程序,使用JNI在Java商店中存储一些对象.(在有人问之前,使用java商店是一个需求,我必须在C中编写一个能够从该商店添加和检索对象的客户端).
我制作了程序并尝试添加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);
}
}
Run Code Online (Sandbox Code Playgroud)
java端接收byte []中的数据并将其存储在哈希表中.问题是,每次代码运行时,内存只会累加而且永远不会释放.我试图添加1 MB对象并进行调试.
当我调用NewByteArray时,进程内存增加1MB.但是当调用CallStaticBooleanMethod时,进程内存增加4MB.对ReleaseByteArrayElements的调用根本不会释放任何内存.
如果我在此之后添加另一个1MB对象,那么当我调用NewByteArray时进程内存保持不变,当我调用CallStaticBooleanMethod时它增加1MB但在我尝试释放字节数组时保持相同.
Xeo*_*eor 17
当您调用New ...函数时,您将创建一个"本地引用" - 在本地堆栈框架中引用此对象.这样可以在您仍然需要时阻止Java VM来自GC.如果要实现一些本机方法,这很好 - 它的本地帧仅为方法调用持续时间创建.但是当你从一个原生的java连接线程创建对象时,它就会绑定到这个线程堆栈帧,只有这个线程才会销毁它.
因此,当您完成对象时,可以调用DeleteLocalRef()来告诉您不再需要它.或者,您可以使用PushLocalFrame()/ PopLocalFrame()对围绕整个add()函数,以在其持续时间内创建单独的本地帧.
| 归档时间: |
|
| 查看次数: |
15962 次 |
| 最近记录: |