首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JNA内存清理

JNA内存清理
EN

Stack Overflow用户
提问于 2021-10-04 11:52:15
回答 2查看 494关注 0票数 1

根据内存类的南国防军文档,当内存需要释放不再具有引用的内存时,需要调用finalize()方法。但是在JNA实例中,有人提到内存对象在超出作用域时会被释放。

代码语言:javascript
复制
// note: like Memory, StringArray will free the contiguous block of memory it copied the Strings into when the instance goes out of scope

问题如下:

  • 这是否意味着,当内存类对象超出作用域并释放底层本机内存时,它会在内部调用finalize()?
  • StringArray类和内存类在行为w.r.t方面是相同的。内存管理?怎么做呢?
EN

回答 2

Stack Overflow用户

发布于 2021-10-05 02:25:24

更新:

从JNA5.12.1开始,JNA的Memory类不再使用finalize()释放内存。它注册了一个Cleaner (基于JDK9+ Cleaner实现的自定义内部类),它使用一个单独的线程释放本机内存。

随着这一变化,Memory被称为Closeable (JDK6),它在JDK7+实现中扩展了AutoCloseable。您可以只通过调用close()或更好的方法释放本机内存,在try-with-resources块中分配内存:

代码语言:javascript
复制
try (Memory m = new Memory(123)) {
  // use m
}

原始答案:

为了根据所提出的具体问题详细说明Matthias Bl sing的答复,我想补充几点:

  • 通常不会直接调用finalize()。JVM将其作为垃圾收集过程的一部分进行调用。
  • Memory中,finalize()方法只调用dispose()方法。如果您真的想立即清除内存,这将是调用的首选方法。但是dispose()protected,所以如果您真的觉得需要清理本地内存分配,就需要扩展Memory来利用这个方法。
    • 您可能考虑的其中一个子类是扩展Closeable的子类,其中close()方法实现从超类调用dispose()。然后,例如,您可以使用一个try with资源块,并在块末尾清理本地内存(资源)。当然,在GC之前,Java对象仍然存在。
    • 请注意,释放本机内存需要付出处理成本,除非您真的缺少内存,否则它不会获得太多的内存,因为您仍然拥有与对象关联的Java堆内存,直到它被GC_d所关联。如果您缺少内存,并且需要达到该级别的详细信息来控制本机分配清理的时间,那么您可能想直接转到malloc()free()自己调用它,并在更高的级别控制它,也许可以回收/重用它……

您还询问了StringArray,但是与Memory更接近的是作为数组成员的NativeString对象。实际上,它们的内部实现是一个StringMemory对象,它扩展了Memory,因此它的行为是相同的;也就是说,通过dispose()通过finalize()将本机内存通过finalize()进行free(),此时NativeString是由JVM垃圾收集的。

票数 2
EN

Stack Overflow用户

发布于 2021-10-04 19:35:26

JNA的Memory实现依赖于java垃圾收集(GC)。Java没有显式获取对象内存的功能,保存对象数据所需的内存由VM管理,在实例化对象时分配。

GC是一个进程,它释放所有不再引用的内存。Java中的所有类都可以声明一个方法finalize,当该类的对象即将被清除时,GC将调用该方法,并为对象提供进行一些最终清理工作的选项。如果使用JNA,此清理将释放本机内存,该内存分配到GC控制区域之外。

应该注意的是,使用finalize是不可取的,不应该再这样做,但是改用替代方法也意味着引入稍微不同的行为,这也是JNA仍然依赖GC进行清理的原因之一。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69435539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档