Java堆外内存之二:堆外内存使用总结

时间:2024-01-12 20:36:38

目录:

堆外内存操作类ByteBuffer

DirectBuffer

Unsafe(java可直接操作内存(),挂起与恢复,CAS操作)

  有时候对内存进行大对象的读写,会引起JVM长时间的停顿,有时候则是希望最大程度地提高JVM的效率,我们需要自己来管理内存(看起来很像是Java像C++祖宗的妥协吧)。据我所知,很多缓存框架都会使用它,比如我以前使用过的EhCache(给它包装了个酷一点的名字,叫BigMemory),以及现在项目中的Memcached等。

使用堆外内存,就是为了能直接分配和释放内存,提高效率。JDK5.0之后,代码中能直接操作本地内存的方式有2种:使用未公开的Unsafe和NIO包下ByteBuffer。

二、堆外内存的大小设置

可以通过设置-XX:MaxDirectMemorySize=10M控制堆外内存的大小,默认的情况下堆外内存大小是64M。

Java堆外内存之二:堆外内存使用总结

二、堆外内存的回收

见《堆外内存回收方法

三、堆外内存的监控

通过查看Bits的maxMemory和reservedMemory属性来监控使用情况。

package com.dfs.util.base;

import java.lang.reflect.Field;

public class CollectDirectMemoryInfo {

    /**
* @VM args:-XX:MaxDirectMemorySize=10m
*/
public static void main(String[] args) throws NoSuchFieldException, SecurityException, ClassNotFoundException,
IllegalArgumentException, IllegalAccessException {
// Class c = java.nio.Bits.class; //无法访问
Class c = Class.forName("java.nio.Bits");
Field maxMemory = c.getDeclaredField("maxMemory");
maxMemory.setAccessible(true);
Field reservedMemory = c.getDeclaredField("reservedMemory");
reservedMemory.setAccessible(true);
synchronized (c) {
Long maxMemoryValue = (Long) maxMemory.get(null);
Long reservedMemoryValue = (Long) reservedMemory.get(null);
System.out.println("maxMemoryValue:" + maxMemoryValue / (1024 * 1024) + "m");
System.out.println("reservedMemoryValue:" + reservedMemoryValue / 1024 * 1024 + "m");
}
}
}

运行结果:

Java堆外内存之二:堆外内存使用总结

四、堆外内存操作类

4.1、Unsafe类

见《Java堆外内存之四:直接使用Unsafe类操作堆外内存

4.2、NIO的ByteBuffer来操作堆外内存

见《Java堆外内存之五:堆外内存管理类ByteBuffer