JVM内存模型之直接内存

直接内存
又称堆外内存,也就是说这不是jvm运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,但这部分也会被频繁的使用,而且也可能导致OOM。

堆外内存有什么优点呢?
1 减少了垃圾回收的工作,因为垃圾回收会暂停其他的工作
2 可以提高性能,避免java堆和native堆(直接内存)来回复制数据。

使用场景
1.在JDK1.4之后加入了NIO,引入了一种基于通道与缓冲区的I/O方式,它可以使用Native库函数直接分配堆外内存,然后通过DirectByteBuffer对象作为这块内存的引用来进行操作,jvm会自动对这部分的堆外内存进行回收。
2.使用jdk内部未对外公开的unsafe来直接使用堆外内存,但不会被JVM回收

例子


/**
 * Created by shengjk1 on 2017/8/8
 * 会自动回收的
 */
//-verbose:gc -XX:+PrintGCDetails -XX:MaxDirectMemorySize=40M
public class TestDirectByteBuffer {
    public static void main(String[] args) {

        while (true){
            ByteBuffer buffer=ByteBuffer.allocateDirect(10*1024*1024);
        }
    }
}
/**
 * Created by shengjk1 on 2017/8/8
 * 不会自动回收
 */
public class TestUnsafeMemo {

    public static Unsafe getUnsafeInstance() throws Exception
    {
        // 通过反射获取rt.jar下的Unsafe类
        Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
        theUnsafeInstance.setAccessible(true);
        // return (Unsafe) theUnsafeInstance.get(null);是等价的
        return (Unsafe) theUnsafeInstance.get(Unsafe.class);
    }

    public static void main(String[] args) throws Exception {
        Unsafe unsafe = getUnsafeInstance();

        while (true){
            long point=unsafe.allocateMemory(20*1024*1024);
            System.out.println(unsafe.getByte(point+1));

//          unsafe.freeMemory(point);
        }
    }
}

你可能感兴趣的:(地基之实,JVM)