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 产生的堆外内存就是这么做的。

原文地址:https://www.cnblogs.com/allenwas3/p/12342189.html

时间: 2024-11-05 22:47:49

java 堆外内存使用的相关文章

java堆外内存 (直接内存)

java堆外内存 (直接内存 非托管内存) 堆外内存的好处是: 可以扩展至更大的内存空间.比如超过1TB甚至比主存还大的空间. 理论上能减少GC暂停时间. 可以在进程间共享,减少JVM间的对象复制,使得JVM的分割部署更容易实现. 它的持久化存储可以支持快速重启,同时还能够在测试环境中重现生产数据. 例如NIO为了高效,提供了ByteBuffer ps:进程间通信的方法除了管道,信号,套接字等常规方法,共享内存,读写文件也可以实现进程间的通信. http://www.importnew.com/

google-perftools 分析JAVA 堆外内存

google-perftools 分析JAVA 堆外内存 分类: j2se2011-08-25 21:48 3358人阅读 评论(4) 收藏 举报 javahbasehtml工具os 原文转自:http://koven2049.iteye.com/blog/1142768,所有权利归原作者所有 最近线上运行的hbase发现分配了16g内存,但是实际使用了22g,堆外内存达到6g.感觉非常诡异.堆外内存用一般的工具很难查看,可以通过google-perftools来跟踪: http://code.

JAVA堆外内存

JVM可以使用的内存分外2种:堆内存和堆外内存. 堆内存完全由JVM负责分配和释放,如果程序没有缺陷代码导致内存泄露,那么就不会遇到java.lang.OutOfMemoryError这个错误. 使用堆外内存,就是为了能直接分配和释放内存,提高效率.JDK5.0之后,代码中能直接操作本地内存的方式有2种:使用未公开的Unsafe和NIO包下ByteBuffer. 关于Unsafe对象的简介和获取方式,可以参考:http://blog.csdn.net/aitangyong/article/det

Java堆外内存的使用

堆外内存的回收见HeapByteBuffer和DirectByteBuffer以及回收DirectByteBuffer 基本类型长度 在Java中有很多的基本类型,比如: byte,一个字节是8位bit,也就是1B short,16位bit,也就是2B int,32位bit,也就是4B long, 64位bit,也就是8B char,16位bit,也就是2B float,32位bit,也就是4B double,64位bit,也就是8B 不同的类型都会按照自己的位数来存储,并且可以自动进行转换提升

Java 堆外内存

入口ByteBuffer.allocateDirect public static ByteBuffer allocateDirect(int capacity) { return new DirectByteBuffer(capacity); } DirectByteBuffer构造函数 DirectByteBuffer(int cap) { // package-private super(-1, 0, cap, cap); boolean pa = VM.isDirectMemoryPag

Java 堆外内存回收原理

原文: https://mp.weixin.qq.com/s?__biz=MzUyMDE1ODQ3NQ==&mid=2247483773&idx=1&sn=24f9eb05ebb39642de4b4951c6b11eaf&chksm=f9efed19ce98640fb65a87b82a85f78fa1eed0e2b5229a4d49a7c17baac95fe5c3ed29086c96&token=1716214908&lang=zh_CN 堆外内存简介Dir

JVM - 堆外内存

看了不少资料,总结下: 堆外内存 / 直接内存(Direct Memory)JDK1.4中引入的NIO类,基于channel和Buffer的I/O方式,可用Native库直接分配堆外内存,然后利用一个存储在堆中的DirectByteBuffer对象作为这块内存引用来操作.避免了在Java堆和Native堆中来回复制数据. 优点 1.堆外内存不影响 JVM GC,程序会减少 Full GC. 2 IO 操作使用堆外内存比堆内存快.因为堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在

JVM初探- 使用堆外内存减少Full GC

JVM初探-使用堆外内存减少Full GC 标签 : JVM 问题: 大部分主流互联网企业线上Server JVM选用了CMS收集器(如Taobao.LinkedIn.Vdian), 虽然CMS可与用户线程并发GC以降低STW时间, 但它也并非十分完美, 尤其是当出现Concurrent Mode Failure由并行GC转入串行时, 将导致非常长时间的Stop The World(详细可参考JVM初探- 内存分配.GC原理与垃圾收集器). 解决: 由GCIH可以联想到: 将长期存活的对象(如L

java中使用堆外内存,关于内存回收需要注意的事和没有解决的遗留问题(等大神解答)

JVM可以使用的内存分外2种:堆内存和堆外内存,堆内存完全由JVM负责分配和释放,如果程序没有缺陷代码导致内存泄露,那么就不会遇到java.lang.OutOfMemoryError这个错误.使用堆外内存,就是为了能直接分配和释放内存,提高效率.JDK5.0之后,代码中能直接操作本地内存的方式有2种:使用未公开的Unsafe和NIO包下ByteBuffer. 关于Unsafe对象的简介和获取方式,可以参考我的另一篇博客  java获取Unsafe类的实例和取消eclipse编译的错误  使用By