|
|
1
21
直接NIO缓冲区使用非托管内存。这意味着它们是在本机堆上分配的,而不是在Java堆上分配的。因此,只有当JVM在Java堆上而不是在本机堆上耗尽内存时,才会释放它们。换句话说,它是非托管的=由您来管理它们。不鼓励强制垃圾收集,并且在大多数情况下都无法解决此问题。 当您知道直接NIO缓冲区对您来说已经无用时,您必须使用它的sun.misc.Cleaner(StaxMan是对的)释放它的本机内存,并调用clean()(Apache Harmony除外)、call free()(Apache Harmony)或使用更好的公共API(可能在Java中>12、扩展自动关闭功能的自动清洗。 这不是JOGL的工作,您可以使用普通Java代码自己完成。 My example 在GPL v2和 this example 是在一个更宽松的许可下。 My latest example 甚至可以与Java1.9一起使用,并且支持OpenJDK、Oracle Java、Sun Java、Apache Harmony、GNU类路径和Android。您可能需要删除一些语法上的糖分才能使其与Java一起工作<1.7(多重捕获、钻石和仿制药)。 参考: http://www.ibm.com/developerworks/library/j-nativememory-linux/
参考: http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#direct This solution 集成在Java 14中:
您可以通过调用 MemorySegment.ofByteBuffer(ByteBuffer) ,获取其内存地址并在Java 16中释放它(这是一种受限方法):
请注意,您仍然需要在许多非常重要的情况下使用反射,以便找到可以释放的缓冲区,通常是当您的直接NIO缓冲区不是ByteBuffer时。 注: sun.misc.Cleaner已被移动 进入 jdk.internal.ref.Cleaner 在模块“Java.base”中的Java1.9中,后者实现了Java.lang.Runnable(感谢Alan Bateman提醒我这一区别),时间很短,但是 it's no longer the case . 您必须调用sun.misc.Unsafe.invokeCleaner(),这是 done in JogAmp's Gluegen . 我更喜欢使用清洁剂作为一种可运行的清洁剂,因为它避免了依赖sun.misc.Unsafe,但它现在不起作用。 我的最后一个建议适用于Java9、10、11和 12 My very latest example 需要使用孵化功能(需要Java>=14) 但是非常非常简单。 a good example in Lucene 在更宽松的许可下。 |
|
|
2
3
直接缓冲区很棘手,并且没有通常的垃圾收集保证-有关更多详细信息,请参阅: http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#direct 如果您遇到问题,我建议分配一次并重新使用缓冲区,而不是重复分配和取消分配。 |
|
|
3
2
解除分配的方式很糟糕——软引用基本上被插入到一个更干净的对象中,当拥有ByteBuffer的对象被垃圾收集时,该对象就会进行解除分配。但这并不能保证能及时调用。 |
|
|
4
0
释放直接缓冲区是垃圾收集器在标记ByteBuffer对象后的一段时间内完成的一项工作。
|
|
|
5
0
在网络中使用信息 gouessej's answer ,我能够将这个实用程序类放在一起,以释放给定ByteBuffer的直接内存分配。当然,这只能作为最后的手段,不应该真正用于生产代码中。 在JavaSE版本10.0.2中测试和工作。
|
|
|
6
-1
与滥用非公共API的反射不同,您可以完全在受支持的公共API中轻松地实现这一点。 编写一些JNI,用NewDirectByteBuffer包装malloc(记住设置顺序),并编写一个类似的函数来释放它。 |
|
|
user29759326 · 如何返回递归函数中的最后一个值? 1 年前 |
|
|
malife89 · 将java中的字符串读取为正确的日期格式 1 年前 |
|
|
Tim · 在java中,有没有更快的方法将字节数组写入文件? 1 年前 |
|
|
rudraraj · java中未声明最终变量 1 年前 |
|
|
Bala Ji · 以下BFS的实施效率如何? 1 年前 |