涉及没有保证析构函数的语言的非 gced 内存的语言绑定?
当有人从 C 库到 Java(或任何其他没有保证运行的析构函数的垃圾收集语言)进行绑定时,他们如何处理非垃圾收集内存的正确释放?
编辑: 我想到的(我知道这在我原来的问题中没有明确说明)是当一块非 gc'ed 内存保存对其他非 gc'ed 资源的引用时,当该对象被释放时需要释放这些资源。释放了。例如,如果您有一个非 gc 链表节点,它是一长串此类节点的头部,并且您希望 gc 系统最终自动清理它,那么如何设置呢?
When someone is making bindings from a C library to Java (or any other garbage-collected language without destructors that are guaranteed to run), how do they deal with proper deallocation of non-garbage-collected memory?
EDIT:
What I'm thinking of (I know this isn't explicitly state in my original question) is when a piece of non-gc'ed memory holds references to other non-gc'ed resources that need to be freed when that object is freed. For example, if you have a non-gc'ed linked list node that is the head of a long list of such nodes and you want to have the gc system clean it up automatically eventually, how do you set that up?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在java中,您有 finalize () 概念。您可以在那里释放 C 内存。
但是,可能更好的方法是使用 PhantomReferences< /a> 以及 参考队列。您可以扩展 PhantomReference 类,以便它保存一些 id 或指针或任何指向您需要释放的 C 端内存的内容。当它在 ReferenceQueue 中排队时,您可以释放该 id 指向的 C 端内存 - Java 对象保证不再“在 Java 中”存在。
In java, you have the finalize() concept. You can free the C-memory there.
However, probably a better way is to use PhantomReferences along with a ReferenceQueue. You can extend the PhantomReference class so that it holds some id or pointer or whatever to the C-side memory you need to free. When it is enqueued in the ReferenceQueue, you can then free the C-side memory that this id points to - the Java object is guaranteed to not be in existence "in Java" anymore.
他们通常提供 API 来创建和发布参考。
例如,Java 的本机接口提供全局引用,允许将 Java 对象固定在内存中,直到 C 程序通过
NewGlobalRef
和DeleteGlobalRef
,并且它还提供本地引用,该引用仅在 Java 将控制权移交给 C 时持续存在:
JVM 嵌入 API 提供了类似的机制,允许将对象固定在内存中,直到C程序确定用它就完成了。
Python 的 C 扩展 API 提供了与 JNI 类似的 API。
python 名称反映了 python 使用引用计数*这一事实,但 API 与 JNI 中的 API 基本相同,JNI 基于非引用计数垃圾收集器——您有一个函数可以固定由解释器管理的内存区域以及将先前固定的区域释放回解释器的一个。
* - python 不是真正的引用计数方法。在同一页中,“虽然 Python 使用传统的引用计数实现,但它还提供了一个循环检测器,可以检测引用循环。”
They typically provide APIs to create and release a reference.
For example, Java's Native Interface provides global references that allow pinning an Java object in memory until the C program is done with it via
NewGlobalRef
andDeleteGlobalRef
and it also provides local refs that only last as long as Java has handed over control to C for:
The JVM embedding API provides a similar mechanism which allows pinning of an object in memory until the C program determines it is done with it.
Python's C extension API provides a similar API to the JNI.
The python names reflect the fact that python uses reference counting* but the API is basically the same as that in JNI which is based on a non-ref counting garbage collector -- you have one function that pins a region of memory managed by the interpreter and one that releases a previously pinned region back to the interpreter.
* - python isn't a true ref-counting approach. From the same page "While Python uses the traditional reference counting implementation, it also offers a cycle detector that works to detect reference cycles."
当使用 Java 等语言的绑定时,其他语言机器会保存每个分配的对象的引用计数器。 API 应该提供增加或减少这些计数器的方法,以指示您的 C 程序持有对其他机器对象的引用的机器。如果 C 程序没有对给定对象的引用,引用计数器可能会达到 0,而其他语言机器将可以自由地对其进行垃圾收集。但是,您可能无法要求机器释放给定的对象。
When using bindings with languages such as Java, the other language machine holds reference counters for each allocated object. The API should give methods to increase or decrease theses counters to indicate the machine that your C program holds reference to the other machine objects. If C program does not have references to a given object, the reference counter may reach 0 and the other language machine will be free to garbage collect it. However, you may not be able to ask the machine to release a given object.