java语言中可以直接操作堆外内存的DirectByteBuffer

参考文档:

Java中四种引用类型

Unsafe类详解

Java直接内存分配与释放原理

DirectByteBuffer是java中直接进行堆外内存管理的API,堆外内存可以直接和系统内存进行交互,从而减少一次JVM内存-系统内存之间的交互,提高I/O效率。所以需要学习一下这个类的构造函数、了解背后的设计思想,提高自己对java语言的理解,从而写出更优雅的代码。

1.入口
通过ByteBuffer.allocateDirect方法进行构造

在这里插入图片描述

在这里插入图片描述
2.DirectByteBuffer的构造函数
在这里插入图片描述
2.1 准备内存
2.1.1SharedSecrets类

static void reserveMemory(long size, int cap) {

	   //初始化maxMemory 
        if (!memoryLimitSet && VM.isBooted()) {
            maxMemory = VM.maxDirectMemory();
            memoryLimitSet = true;
        }

        // 尝试预开辟内存
        if (tryReserveMemory(size, cap)) {
            return;
        }

        final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();

       // 尝试执行Cleaner来释放直接内存,直到内存空间足够
        while (jlra.tryHandlePendingReference()) {
            if (tryReserveMemory(size, cap)) {
                return;
            }
        }

        //系统GC
        System.gc();

        //间隔轮训尝试开辟内存,轮询时间是1ms的2^
        boolean interrupted = false;
        try {
            long sleepTime = 1;
            int sleeps = 0;
            while (true) {
                if (tryReserveMemory(size, cap)) {
                    return;
                }
                if (sleeps >= MAX_SLEEPS) {
                    break;
                }
                if (!jlra.tryHandlePendingReference()) {
                    try {
                        Thread.sleep(sleepTime);
                        sleepTime <<= 1;
                        sleeps++;
                    } catch (InterruptedException e) {
                        interrupted = true;
                    }
                }
            }

            // no luck
            throw new OutOfMemoryError("Direct buffer memory");
  private static boolean tryReserveMemory(long size, int cap) {

       // -XX:MaxDirectMemorySize限制的是总cap,而不是真实的内存使用量,(在页对齐的情况下,真实内存使用量和总cap是不同的)       
        long totalCap;
        while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
            if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
                reservedMemory.addAndGet(size);
                count.incrementAndGet();
                return true;
            }
        }

        return false;
    }

2.2初始化内存
2.3分配内存空间
2.4创建垃圾回收器
2.4.1虚引用
虚引用的概念:无法通过虚引用获取与之关联的实例,当对象被虚引用引用时,发生任何GC的时候,都可以被回收。通常 PhantomReference 与引用队列ReferenceQueue 结合使用,可以实现虚引用关联对象被垃圾回收时能够进行系统通知、资源清理等功能。
当某个被 Cleaner 引用的对象将被回收时,JVM 垃圾收集器会将此对象的引用放入到对象引用pending 链表中,等待Reference-Handler 进行相关处理。其中,Reference-Handler 为一个拥有最高
优先级的守护线程,会循环不断的处理 pending 链表中的对象引用,执行 Cleaner的 clean 方法进行相关清理工作。
在这里插入图片描述

在这里插入图片描述

Deallocator
在这里插入图片描述

Reference类是java引用对象的回收类,他会循环处理被引用的对象,对其进行回收操作
在这里插入图片描述
当DirectByteBuffer被回收时,
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值