通过调用API JNI内存管理 [英] JNI memory management using the Invocation API

查看:117
本文介绍了通过调用API JNI内存管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用JNI方法建立一个Java对象,以它作为参数传递给Java方法,我使用JNI调用API调用,我该如何管理自己的内存?

When I'm building a java object using JNI methods, in order to pass it in as a parameter to a java method I'm invoking using the JNI invocation API, how do I manage its memory?

下面就是我与工作:

我有了析构函数方法是比较复杂的一个C对象免费()。这个C对象要与一个Java对象相关联,一旦应用程序与Java对象完了,我对C的对象不再需要。

I have a C object that has a destructor method that is more complex that free(). This C object is to be associated with a Java object, and once the application is finished with the Java object, I have no more need for the C object.

我创建的Java对象,像这样(检查省略为清楚起见错误):

I am creating the Java object like so (error checking elided for clarity):

c_object = c_object_create ();
class = (*env)->FindClass (env, "my.class.name");
constructor = (*env)->GetMethodID (env, class, "<init>", "(J)V");
instance = (*env)->NewObject (env, class, constructor, (jlong) c_object);

method = (*env)->GetMethodID (env, other_class, "doSomeWork", "(Lmy.class.name)V");
(*env)->CallVoidMethod (env, other_class, method, instance);

所以,现在我与实例来完成,我该怎么办呢?理想情况下,我想离开这个垃圾收集到虚拟机;当它与实例来完成这将是美妙的,如果这也叫 c_object_destroy()在我给它提供的指针。这可能吗?

So, now that I'm done with instance, what do I do with it? Ideally, I'd like to leave the garbage collection up to the VM; when it's done with instance it would be fantastic if it also called c_object_destroy() on the pointer I provided to it. Is this possible?

有一个单独的,但相关的问题有,我在这样的方法创建Java实体的范围做;我必须手动释放,也就是说,构造上面? JNI的文档是正确的内存管理的主体令人沮丧模糊(在我的判断)。

A separate, but related question has to do with the scope of Java entities that I create in a method like this; do I have to manually release, say, class, constructor, or method above? The JNI doc is frustratingly vague (in my judgement) on the subject of proper memory management.

推荐答案

有用于回收本机资源的几个策略(对象,文件描述符等)

There are a couple of strategies for reclaiming native resources (objects, file descriptors, etc.)


  1. 调用的finalize其间释放该资源的JNI()方法。有些人建议对实施完成,基本上你不能真的相信说你的本土资源被不断释放。对于资源,如内存这可能不是问题,但如果你有例如文件,需要在predictable时间被刷新,最后确定()可能不是一个好主意。

  1. Invoke a JNI method during finalize() which frees the resource. Some people recommend against implementing finalize, and basically you can't really be sure that your native resource is ever freed. For resources such as memory this is probably not a problem, but if you have a file for example which needs to be flushed at a predictable time, finalize() probably not a good idea.

手动调用清理方法。如果你有时间点,你知道,资源必须被清理,这非常有用。我用这个方法时,我有一个资源它曾在JNI code卸载DLL之前被释放。为了让以后重新加载DLL,我必须确保该对象试图卸载DLL之前真的释放。只使用敲定(),我也不会获得这样的保证。这可以通过(1)以允许被组合以分配或敲定期间(),或在手动称为清理方法的资源。 (你可能需要在WeakReferences跟踪哪些对象需要都调用它们的清理方法的规范地图。)

Manually invoke a cleanup method. This is useful if you have a point in time where you know that the resource must be cleaned up. I used this method when I had a resource which had to be deallocated before unloading a DLL in the JNI code. In order to allow the DLL to later be reloaded, I had to be sure that the object was really deallocated before attempting to unload the DLL. Using only finalize(), I would not have gotten this guaranteed. This can be combined with (1) to allow the resource to be allocated either during finalize() or at the manually called cleanup method. (You probably need a canonical map of WeakReferences to track which objects needs to have their cleanup method invoked.)

据推测在的PhantomReference 可以用来解决这个问题为好,但我不知道这样的解决办法究竟是如何工作的。

Supposedly the PhantomReference can be used to solve this problem as well, but I'm not sure exactly how such a solution would work.

其实,我有JNI文档上同意你的意见。我觉得 JNI规范格外清晰上最重要的的问题,即使在管理本地及全球引用部分可更为详细阐述。

Actually, I have to disagree with you on the JNI documentation. I find the JNI specification exceptionally clear on most of the important issues, even if the sections on managing local and global references could have been more elaborated.

这篇关于通过调用API JNI内存管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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