我有一个本机应用程序启动JVM并通过JNI API调用一些方法。
粗略地说,本机应用程序:
PushLocalFrame
创建一个新框架;x
,通过JNI调用构造函数;PopLocalFrame(x)
弹出框架;foo(x)
,将创建的对象作为参数传递给CallObjectMethod
;问题是在相同的情况下,步骤5与java.lang.OutOfMemoryError
崩溃。这是意料之外的,因为通常Java函数在从仅JVM应用程序调用时不会占用太多内存。
使用VisualVM进行堆转储我发现有许多“GC根(Java框架)”,我没想到。我最好的解释是:
foo
从x
采取一些领域并存储其中的东西;foo
期间,JVM不能垃圾收集x
,也不能传递存储在其中的任何内容。那么,有没有办法通过JNI接口调用Java方法,让JVM垃圾收集参数?
Weak global references几乎是我想要的,但我不知道如何使用它们,因为理论上它们可以在创建之后立即进行垃圾收集,然后在函数调用中作为参数传递。
在处理本机资源时,您不应指望垃圾收集来释放内存。
相反,为包装本机对象或句柄的每个Java类实现Closable
接口,并确保在解除引用之前关闭每个对象。
您可以使用try (<Allocate Closables Here>) { <Use Them Here> }
语法来自动关闭对象。