涉及语言的非gced内存的语言绑定没有保证的析构函数?

时间:2011-07-26 23:30:16

标签: java c language-binding

如果某人正在从C库绑定到Java(或任何其他垃圾收集语言而没有保证运行的析构函数),那么它们如何处理非垃圾收集内存的正确释放?

编辑: 我正在考虑的事情(我知道这在我的原始问题中没有明确说明)是当一块非gc'ed内存持有对其他非gc'ed资源的引用时,当该对象需要被释放时释放。例如,如果你有一个非gc'ed链表节点,这是一个很长的这类节点列表的头部,你想让gc系统最终自动清理它,你如何设置它?

3 个答案:

答案 0 :(得分:2)

它们通常提供API来创建和发布引用。

例如,Java的Native Interface提供了全局引用,允许在内存中固定Java对象,直到C程序通过NewGlobalRefDeleteGlobalRef

完成它。
  

NewGlobalRef创建对obj参数引用的对象的新全局引用。 obj参数可以是全局或本地引用。必须通过调用DeleteGlobalRef()

明确处理全局引用

并且它还提供了本地引用,只要Java将控制权移交给C:

  

本地引用在本机方法调用期间有效。它们在本机方法返回后自动释放。

JVM embedding API提供了一种类似的机制,允许将对象固定在内存中,直到C程序确定它已完成为止。

Python's C extension API为JNI提供了类似的API。

  

通过调用Py_INCREF()可以将借用的引用更改为自己的引用。

     

当不再需要引用时,引用的所有者负责调用Py_DECREF()

python名称反映了python使用引用计数*这一事实,但API基本上与基于非引用计数垃圾收集器的JNI中的API相同 - 您有一个函数可以管理一个内存管理区域由翻译和一个将先前固定的区域释放回翻译的人。

* - python不是真正的引用计数方法。从同一页面“虽然Python使用传统的引用计数实现,它还提供了一个循环检测器,用于检测参考周期。”

答案 1 :(得分:2)

在java中,您有finalize()概念。你可以在那里释放C-memory。

但是,更好的方法是使用PhantomReferencesReferenceQueue。您可以扩展PhantomReference类,使其保存一些id或指针或任何你需要释放的C端内存。当它在ReferenceQueue中排队时,您可以释放此id指向的C端内存 - 保证Java对象不再存在于“Java”中。

答案 2 :(得分:0)

当使用Java等语言绑定时,另一台语言机器会为每个已分配的对象保存引用计数器。 API应该提供增加或减少这些计数器的方法,以指示您的C程序保持对其他计算机对象的引用的计算机。如果C程序没有对给定对象的引用,则引用计数器可能达到0,而另一台语言机器可以自由地进行垃圾收集。但是,您可能无法要求机器释放给定对象。