JVM内存模型之直接内存

本文介绍了堆外内存(也称为直接内存)的概念及其优劣,并详细探讨了两种使用场景:通过DirectByteBuffer自动回收堆外内存及使用Unsafe手动管理堆外内存的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接内存
又称堆外内存,也就是说这不是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);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shengjk1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值