java 堆外内存使用

Posted 偶尔发呆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 堆外内存使用相关的知识,希望对你有一定的参考价值。

最大堆外内存的配置

-XX:MaxDirectMemorySize=15g

分配堆外内存

java.nio.ByteBuffer#allocateDirect

DirectByteBuffer 类是包权限的,使用 unsafe 分配和回收内存

class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer
    DirectByteBuffer(int cap) {
        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);
        } 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));
        att = null;
    }
    
    private static class Deallocator implements Runnable {
        private static Unsafe unsafe = Unsafe.getUnsafe();

        private long address;
        private long size;
        private int capacity;

        private Deallocator(long address, long size, int capacity) {
            assert (address != 0);
            this.address = address;
            this.size = size;
            this.capacity = capacity;
        }

        public void run() {
            if (address == 0) {
                // Paranoia
                return;
            }
            unsafe.freeMemory(address);
            address = 0;
            Bits.unreserveMemory(size, capacity);
        }

    }
    private final Cleaner cleaner;
}

堆外内存的回收,也受 GC 控制,最终也是调用了 cleaner 的 clean 方法,然后到 Deallocator 的 run 方法、

所以,可以通过反射来主动调用该方法,释放堆外内存。

rocketMQ 释放 mmap 产生的堆外内存就是这么做的。

以上是关于java 堆外内存使用的主要内容,如果未能解决你的问题,请参考以下文章

Java 堆外内存回收原理

java 堆外内存使用

Java堆外内存的使用

Java堆外内存之突破JVM枷锁

jvm调优四:netty堆外内存泄露

java堆外内存 (直接内存)