美文网首页@IT·互联网程序员
Java堆外内存的回收机制

Java堆外内存的回收机制

作者: 薛定谔的猫Plus | 来源:发表于2018-09-21 15:43 被阅读52次

1 堆外内存

JVM启动时分配的内存,称为堆内存,与之相对的,在代码中还可以使用堆外内存,不如Netty,广泛使用了堆外内存,但是这部分内存不归JVM管理,GC算法并不会对它们进行回收,所以使用堆外内存是需要格外小心,以防出现内存泄露。

2 堆外内存的申请和释放

JDK中使用DirectByteBuffer对象来表示堆外内存,可以通过-XX:MaxDirectMemorySize来指定最大的堆外内存,每个DirectByteBuffer对象在初始化时,都会创建一个对应的Cleaner对象,在Cleaner对象回收的时候回收这部分堆外内存。初始化时引用关系如下:


image

其中first是Cleaner类的静态变量,Cleaner对象在初始化时会被添加到Clener链表中,和first形成引用关系,ReferenceQueue是用来保存需要回收的Cleaner对象。

3 Cleaner如何与GC相关联

JDK除了StrongReference、SoftReference和WeakReference之外,还有一种PhantomReference是虚引用,Cleaner就是PhantomReference的子类。(针对这几种引用,后续专题讲解)

当GC时发现它除了PhantomReference外已不可达(持有它的DirectByteBuffer失效了),就会把它放进 Reference类pending list静态变量里。然后另有一条ReferenceHandler线程,名字叫 "Reference Handler"的,关注着这个pending list,如果看到有对象类型是Cleaner,就会执行它的clean(),在最终的处理里会通过Unsafe的free接口来释放DirectByteBuffer对应的堆外内存块。

4 堆外内存基于GC的回收

快速回顾一下堆内的GC机制,当新生代满了,就会发生young gc;如果此时对象还没失效,就不会被回收;撑过几次young gc后,对象被迁移到老生代;当老生代也满了,就会发生full gc。

这里可以看到一种尴尬的情况,因为DirectByteBuffer本身的个头很小,只要熬过了young gc,即使已经失效了也能在老生代里舒服的呆着,不容易把老生代撑爆触发full gc,如果没有别的大块头进入老生代触发full gc,就一直在那耗着,占着一大片堆外内存不释放。

    其实在初始化DirectByteBuffer对象时,如果当前堆外内存的条件很苛刻时,会主动调用System.gc()强制执行FGC。

这时,就只能靠触发system.gc()来救场了。如果还是无法释放,就可能会出现OOM。

  不过很多线上环境的JVM参数有-XX:+DisableExplicitGC,导致了System.gc()等于一个空函数,根本不会触发FGC,这点需要特别关注。

相关文章

  • JVM之Java垃圾回收机制

    为大家推荐一篇写的通俗易懂的关于Java垃圾回收机制的文章理解Java垃圾回收机制 Java主要把内存分为堆内存和...

  • try catch finally

    java的垃圾回收机制不会回收任何的物理资源,垃圾回收机制只回收堆内存中对象所占用的内存 当程序执行try块,ca...

  • Java堆外内存的回收机制

    1 堆外内存 JVM启动时分配的内存,称为堆内存,与之相对的,在代码中还可以使用堆外内存,不如Netty,广泛使用...

  • 对 Java 内存的一些理解-[Android_YangKe]

    Java 垃圾回收机制优点 Java 内存模型 什么是内存抖动 什么是内存泄漏 垃圾回收机制常见算法 Java 垃...

  • Java非堆内存的回收

    jvm的垃圾回收机制大家应该已经很熟了,jvm主要是回收堆内存,而我我们在开发中会遇到在堆外分配内存的情况,那这部...

  • java 内存机制

    Java的内存机制有几点: 1.堆:主要负责保存创建的对象实例,GC主要操作堆空间,及时回收内存空间,以便它用。(...

  • java 垃圾回收机制

    1.gc 是java垃圾回收机制,垃圾回收机制大部分情况会在线程空闲的时候调用。但是在Java堆内存不足的时候也会...

  • Java内存管理机制 ————浅析原理

    java内存管理机制 内存泄漏 内存溢出 内存抖动: 话术整理 首先java的内存管理机制 gc的垃圾回收...

  • Java堆外内存回收原理

    Java 堆外内存回收原理 简书涤生[https://www.jianshu.com/users/150f36a7...

  • Java 堆外内存回收原理

    堆外内存简介 DirectByteBuffer 这个类是 JDK 提供使用堆外内存的一种途径,当然常见的业务开发一...

网友评论

    本文标题:Java堆外内存的回收机制

    本文链接:https://www.haomeiwen.com/subject/vbzanftx.html