java堆外内存回收机制
所属分类 java
浏览量 1525
DirectByteBuffer
使用堆外内存 ,网络 IO,避免堆内存到堆外内存的数据拷贝
Netty 使用堆外内存来实现零拷贝
java.nio.Bits
内部维护着当前已经使用的堆外内存大小
private static volatile long maxMemory = VM.maxDirectMemory();
private static final AtomicLong reservedMemory = new AtomicLong();
private static final AtomicLong totalCapacity = new AtomicLong();
private static final AtomicLong count = new AtomicLong();
Bits.reserveMemory
堆外内存不够时 主动执行 System.gc()
unsafe.allocateMemory 分配内存,返回内存地址,并清 0
Bits.reserveMemory(size, cap);
long base = unsafe.allocateMemory(size);
unsafe.setMemory(base, size, (byte) 0);
cleaner = Clearner.create(this , new Deallocator(base , size , cap));
public class sun.misc.Cleaner extends java.lang.ref.PhantomReference
堆外内存自动回收机制
Cleaner与GC关联
PhantomReference 不会影响GC
GC 添加到 Reference pending list里。
ReferenceHandler线程 处理 pending list, 对于Cleaner 对象 执行clean()
最终调用Unsafe的free接口释放堆外内存
Reference 类内部 static 块启动 ReferenceHandler 线程
手动回收
手动调用 DirectByteBuffer cleaner 的 clean 方法
获取cleaner的两种方式
反射获取
调用 DirectBuffer 的 cleaner 方法
public static void clean(final ByteBufferbyteBuffer) {
if(byteBuffer.isDirect()) {
Field cleanerField = byteBuffer.getClass().getDeclaredField("cleaner");
cleanerField.setAccessible(true);
Cleaner cleaner = (Cleaner) cleanerField.get(byteBuffer);
cleaner.clean();
}
}
public static void clean(final ByteBufferbyteBuffer) {
if(byteBuffer.isDirect()) {
((DirectBuffer)byteBuffer).cleaner().clean();
}
}
Netty使用反射手动回收
上一篇
下一篇
docker常用命令
docker Busybox 实战
java调用c方法JNA实例
ConcurrentHashMap在jdk7和8中的区别
优秀投资者的十大特征
springboot web端口设置三种方式