Examples of forcing freeing of native memory direct ByteBuffer has allocated, using sun.misc.Unsafe?(使用 sun.misc.Unsafe? 强制释放直接 ByteBuffer 已分配的本机内存的示例)
问题描述
JDK 提供了分配所谓的直接 ByteBuffers 的能力,其中内存在 Java 堆之外分配.这可能是有益的,因为垃圾收集器不会触及此内存,因此不会增加 GC 开销:这对于缓存等长寿命事物的属性非常有用.
JDK provides abillity to allocate so-called direct ByteBuffers, where memory is allocate outside of Java heap. This can be beneficial since this memory is not touched by garbage collector, and as such does not contribute to GC overhead: this is a very useful for property for long-living things like caches.
然而,现有实现存在一个关键问题:只有在对拥有的 ByteBuffer 进行垃圾回收时才异步分配底层内存;没有办法强制提前释放.这可能会产生问题,因为 GC 周期本身不受 ByteBuffers 处理的影响,并且考虑到 ByteBuffers 可能驻留在旧代内存区域中,可能会在 ByteBuffer 不再使用数小时后调用 GC.
However, there is one critical problem with existing implementation: underlying memory is only allocated asynchronously when the owning ByteBuffer is garbage-collected; there is no way to force early deallocation. This can be problematic since GC cycle itself is not influenced by handling of ByteBuffers, and given that ByteBuffers are likely to reside in Old Generation memory area, it is possible that GC is called hours after ByteBuffer is no longer in use.
但理论上应该可以直接使用 sun.misc.Unsafe 方法(freeMemory、allocateMemory):这是 JDK 本身用于分配/释放本机内存的方法.查看代码,我看到的一个潜在问题是内存双重释放的可能性——所以我想确保正确清理状态.
But in theory it should be possible to use sun.misc.Unsafe methods (freeMemory, allocateMemory) directly: this is what JDK itself uses for allocating/deallocating native memory.
Looking at code, one potential concern I see is possibility of double-freeing of memory -- so I would want to make sure that state would be properly cleaned.
谁能指点我这样做的代码?理想情况下希望使用它而不是 JNA.
Can anyone point me to code that does this? Ideally would want to use this instead of JNA.
注意:我看到 这个问题有点相关.
NOTE: I saw this question which is sort of related.
看起来指出的答案是好方法:here 是来自 Elastic Search 的代码示例,它使用了这个想法.谢谢大家!
Looks like the answers pointed out are good way to go: here is code example from Elastic Search that uses the idea. Thanks everyon!
推荐答案
使用 sun.misc.Unsafe 几乎不可能,因为分配的本机内存的基地址是 java 的局部变量.nio.DirectByteBuffer 构造函数.
Using sun.misc.Unsafe is hardly possible because base address of the allocated native memory is a local variable of java.nio.DirectByteBuffer constructor.
其实你可以用下面的代码强制释放本机内存:
Actually you can force freeing of native memory with the following code:
import sun.misc.Cleaner;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
...
public static void main(String[] args) throws Exception {
ByteBuffer direct = ByteBuffer.allocateDirect(1024);
Field cleanerField = direct.getClass().getDeclaredField("cleaner");
cleanerField.setAccessible(true);
Cleaner cleaner = (Cleaner) cleanerField.get(direct);
cleaner.clean();
}
这篇关于使用 sun.misc.Unsafe? 强制释放直接 ByteBuffer 已分配的本机内存的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 sun.misc.Unsafe? 强制释放直接 ByteBuffer 已分配的本机内存的示例
基础教程推荐
- Java Swing计时器未清除 2022-01-01
- 大摇大摆的枚举 2022-01-01
- 如何在 JFrame 中覆盖 windowsClosing 事件 2022-01-01
- 验证是否调用了所有 getter 方法 2022-01-01
- Java 实例变量在两个语句中声明和初始化 2022-01-01
- 如何在 Spring @Value 注解中正确指定默认值? 2022-01-01
- 从 python 访问 JVM 2022-01-01
- 多个组件的复杂布局 2022-01-01
- 不推荐使用 Api 注释的描述 2022-01-01
- 在 Java 中创建日期的正确方法是什么? 2022-01-01
