使用JNI从C调用Java code时,内存泄漏 [英] Memory leak when calling java code from C using JNI

查看:361
本文介绍了使用JNI从C调用Java code时,内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个存储使用JNI在Java软件商店某个对象的C程序。 (有人问之前,请使用Java软件商店是这里的需要量,我必须写在C客户端,将能够从这个存储区中添加和检索对象)。

I have a C program that stores some object in java store using JNI. (Before someone ask, using java store is a requirment here and I have to write a client in C which would be able to add and retrieve objects from this store).

我做了方案,并尝试添加大小1KB的100000的对象。但只增加50000对象后我得到内存不足的消息(请注意,我打印这些内存不足消息,每当我无法分配使用NewStringUTF和NewByteArray功能一个新的字符串或字节数组)。那时我的应用程序正在使用的内存只有80MB。我不为什么这些方法返回NULL。是否有我丢失的东西。

I made the program and tried to add 100000 object of size 1KB. But after adding only 50000 objects I am getting 'out of memory' messages (please note that I am printing these 'out of memory' messages whenever I am unable to allocate a new string or byte array using NewStringUTF and NewByteArray functions). At that time my application is using only 80MB of memory. I dont why these methods are returning NULL. Is there something I am missing.

此外,内存不断即使我释放字节数组和字符串的Java创建的提高。

Furthermore, the memory keeps on increasing even though I am releasing byte array and string created for java.

下面是源$ C ​​$ C。

Here is the source code.

    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端临危字节[]在哈希表中的数据并将其存储。
问题是,每次在code运行内存只有相加和永远不会释放。
我试图添加1 MB对象并调试了。

The java side recieves the data in byte[] and stores it in a hashtable. The issue is that everytime the code runs the memory only adds up and is never released. I tried to add 1 MB object and debugged it.

由1MB的进程内存的增加,当我打电话NewByteArray。但是,当CallStaticBooleanMethod被称为由4MB进程内存的增加。并调用ReleaseByteArrayElements根本不释放任何内存。

The process memory increases by 1MB when I call NewByteArray. But when CallStaticBooleanMethod is called the process memory increase by 4MB. And the call to ReleaseByteArrayElements do not release any memory at all.

如果我在此之后再添1MB的对象,那么进程内存当我打电话NewByteArray,它由1MB提升当我打电话CallStaticBooleanMethod但仍然是相同的,当我尝试释放字节数组保持不变。

If I add another 1MB object after this, then process memory remains same when I call NewByteArray and it increase by 1MB when I call CallStaticBooleanMethod but remains the same when I try to release the byte array.

推荐答案

当你调用新...功能,您可以创建一个本地参考 - 引用此对象在本地堆栈帧。这prevents Java虚拟机从GC这个对象,而你仍然需要它。这是好的,如果你正在实施一些本地方法 - 只为方法通话时间创建了本地帧。但是,当你从一个本地Java连接的线程建立的对象,它成为绑定到该线程的堆栈帧,这将只与此线程被破坏。

When you call New... functions, you create a "local reference" - reference to this object in local stack frame. This prevents Java VM from GC this object while you still need it. This is fine if you are implementing some native method - its local frame is created only for method call duration. But when you are creating object from a native java-attached thread, it becomes bound to this thread stack frame, which will be destroyed only with this thread.

所以,当你与一个对象做,你可以调用DeleteLocalRef()来告诉你不再需要它。或者你可以环绕整个add()函数与对PushLocalFrame()/ PopLocalFrame(中),以单独的本地帧持续时间。

So, when you done with an object you can call DeleteLocalRef() to tell you no longer need it. Or you can surround the whole add() function with pair of PushLocalFrame()/PopLocalFrame() to make a separate local frame for its duration.

这篇关于使用JNI从C调用Java code时,内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆