JVM内存结构(三)(直接内存)

DirectMemory是Java中的非JVM内存,常用于NIO操作,提供高速读写但需手动管理。通过Unsafe对象进行分配和回收,使用Cleaner确保对象被回收时释放内存。禁用显示GC不会立即释放直接内存,需要等待GC或手动释放。

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

6.直接内存

6.1 定义

​ Direct Memory

  • 不属于jvm,属于操作系统内存

  • 常见与NIO操作时,用于数据缓冲

  • 分配回收成本高,但读写性能高。

  • 不受jvm内存回收管理 ,直接内存对象是通过Unsafe对象来管理的。

6.2案例
  1. 在使用传统FileInputStream 读文件,FileOutputStream 写文件。读取速度较慢。byte{}[]

  2. Java不能直接操作系统内存缓存区

  3. 使用FileChannel BteBuffer 直接内存
    Java可以直接操作Direct memory

  • Java不能直接操作系统内存,但是可以操作direct Memory(直接内存)

ByteBuffer源码

DirectByteBuffer(int cap) {                   // package-private

    super(-1, 0, cap, cap);
    boolean pa = VM.isDirectMemoryPageAligned();
    int ps = Bits.pageSize();
    long size = Math.max(1L, (long)cap + (pa ? ps : 0));
    Bits.reserveMemory(size, cap);

    long base = 0;
    try {
        base = unsafe.allocateMemory(size);   //unsafe 分配内存
    } catch (OutOfMemoryError x) {
        Bits.unreserveMemory(size, cap);
        throw x;
    }
    unsafe.setMemory(base, size, (byte) 0);
    if (pa && (base % ps != 0)) {
        // Round up to page boundary
        address = base + ps - (base & (ps - 1));
    } else {
        address = base;
    }
    cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); //直接内存释放必须主动调用unsafe对象
    att = null;		//Cleaner 虚引用对象,当关联对象被回收,就会触发虚引用的clean();



}
6.3 分配和回收原理
  • 使用了 Unsafe 对象完成直接内存分配和回收,并且回收需要主动调用freeMemory方法

  • ByteBuffer的实现类内部,使用了Cleaner(虚引用) 来检测ByteBuffer 对象,一旦ByteBuffer对象被垃圾回收,那么就会由ReferenceHandler线程通过Cleaner的clean方法调用freeMemory来释放内存。

  • -XX:+DisableExplicitGC 禁用显示的GC (System.gc(); Full GC) 直接内存不会被释放,要等到真正GC的时候才会被释放,可以直接使用Unsafe对象释放。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值