目录:
《Unsafe(java可直接操作内存(),挂起与恢复,CAS操作)》
有时候对内存进行大对象的读写,会引起JVM长时间的停顿,有时候则是希望最大程度地提高JVM的效率,我们需要自己来管理内存(看起来很像是Java像C++祖宗的妥协吧)。据我所知,很多缓存框架都会使用它,比如我以前使用过的EhCache(给它包装了个酷一点的名字,叫BigMemory),以及现在项目中的Memcached等。
使用堆外内存,就是为了能直接分配和释放内存,提高效率。JDK5.0之后,代码中能直接操作本地内存的方式有2种:使用未公开的Unsafe和NIO包下ByteBuffer。
二、堆外内存的大小设置
可以通过设置-XX:MaxDirectMemorySize=10M控制堆外内存的大小,默认的情况下堆外内存大小是64M。
二、堆外内存的回收
见《堆外内存回收方法》
三、堆外内存的监控
通过查看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"); } } }
运行结果:
四、堆外内存操作类
4.1、Unsafe类
见《Java堆外内存之四:直接使用Unsafe类操作堆外内存》