JVM堆外内存的回收机制分析
本文来说下堆外内存的回收机制分析
文章目录
- 堆外内存
- 堆外内存的申请和释放
- 堆外内存的回收机制
- 本文小结
堆外内存
JVM启动时分配的内存,称为堆内存,与之相对的,在代码中还可以使用堆外内存,比如Netty,广泛使用了堆外内存,但是这部分的内存并不归JVM管理,GC算法并不会对它们进行回收,所以在使用堆外内存时,要格外小心,防止内存一直得不到释放,造成线上故障。
堆外内存的申请和释放
JDK的ByteBuffer类提供了一个接口allocateDirect(int capacity)进行堆外内存的申请,底层通过unsafe.allocateMemory(size)实现,接下去看看在JVM层面是如何实现的。
可以发现,最底层是通过malloc方法申请的,但是这块内存需要进行手动释放,JVM并不会进行回收,幸好Unsafe提供了另一个接口freeMemory可以对申请的堆外内存进行释放。
堆外内存的回收机制
如果每次申请堆外内存,都需要在代码中显示的释放,对于Java这门语言的设计来说,显然不够合理,既然JVM不会管理这些堆外内存,它们是如何回收的呢?
DirectByteBuffer
JDK中使用DirectByteBuffer对象来表示堆外内存,每个DirectByteBuffer对象在初始化时,都会创建一个对用的Cleaner对象,这个Cleaner对象会在合适的时候执行unsafe.freeMemory(address),从而回收这块堆外内存。
当初始化一块堆外内存时,对象的引用关系如下:
其中first是Cleaner类的静态变量,Cleaner对象在初始化时会被添加到Clener链表中,和first形成引用关系,ReferenceQueue是用来保存需要回收的Cleaner对象。如果该DirectByteBuffer对象在一次GC中被回收了。
此时,只有Cleaner对象唯一保存了堆外内存的数据(开始地址、大小和容量),在下一次FGC时,把该Cleaner对象放入到ReferenceQueue中,并触发clean方法。
Cleaner对象的clean方法主要有两个作用:
- 把自身从Clener链表删除,从而在下次GC时能够被回收
- 释放堆外内存
public void run() {if (address == 0) {// Paranoiareturn;}unsafe.freeMemory(address);address = 0;Bits.unreserveMemory(size, capacity);
}
如果JVM一直没有执行FGC的话,无效的Cleaner对象就无法放入到ReferenceQueue中,从而堆外内存也一直得不到释放,内存岂不是会爆?其实在初始化DirectByteBuffer对象时,如果当前堆外内存的条件很苛刻时,会主动调用System.gc()强制执行FGC。
不过很多线上环境的JVM参数有-XX:+DisableExplicitGC,导致了System.gc()等于一个空函数,根本不会触发FGC,这一点在使用Netty框架时需要注意是否会出问题。
本文小结
本文介绍了JVM堆外内存的回收机制。
JVM堆外内存的回收机制分析相关推荐
- 一次完整的JVM堆外内存泄漏故障排查记录
前言 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指令和工具分享,希望对大家有所帮助. 在整个排查过程中,我也走了不少弯路,但是在文章中我 ...
- jvm堆外内存--DirectByteBuffer
jvm的堆外内存本来是高贵而神秘的东西,只在一些缓存方案实战级别才会出现.但自从用了Netty等高并发IO框架后,就变成了天天与堆外内存打交道,在mina,netty等nio框架中屡见不鲜.堆外内存的 ...
- jvm堆外内存排查详解
文章目录 前言 一.堆外内存排查 1.背景 2.内存对比 3.堆外内存检查 4.排查堆外内存 5.glibc内存泄露 结尾 前言 内存泄漏想必大家并不陌生,对于jvm的内存泄漏,有很多排查手段和方便的 ...
- jvm 堆外内存_NIO效率高的原理之零拷贝与直接内存映射
更多内容,欢迎关注微信公众号:全菜工程师小辉~ 前言 在笔者上一篇博客,详解了NIO,并总结NIO相比BIO的效率要高的三个原因,彻底搞懂NIO效率高的原理. 这篇博客将针对第三个原因,进行更详细的讲 ...
- jvm 堆外内存_jvm┃java内存区域,跳槽大厂必会知识点
正文约: 2000字 预计阅读时间: 6分钟 文章首发于我的微信公众号:哪儿来的moon,欢迎大家关注 目录 目录 前言 正文 1.程序计数器 2.虚拟机栈 3.本地方法栈 4.堆 5.方法区 6.直 ...
- jvm 堆外内存_一图解千愁,jvm内存从来没有这么简单过!
原创:小姐姐味道,欢迎分享,转载请保留出处. 看到这张图的同学,千万不要到处分享.我们仅限于小范围讨论,因为这张图威力很大,是我花了10年时间才画出来的! 了解了这张图,会让你对JVM内存的划分有更深 ...
- 一文探讨堆外内存的监控与回收
引子 记得那是一个风和日丽的周末,太阳红彤彤,花儿五颜六色,96 年的普哥微信找到我,描述了一个诡异的线上问题:线上程序使用了 NIO FileChannel 的 堆内内存作为缓冲区,读写文件,逻辑可 ...
- java 查看堆外内存占用_如何监控和诊断JVM堆内和堆外内存使用?
上一讲我介绍了 JVM 内存区域的划分,总结了相关的一些概念,今天我将结合 JVM 参数.工具等方面,进一步分析 JVM 内存结构,包括外部资料相对较少的堆外部分. 今天我要问你的问题是,如何监控和诊 ...
- Java堆外内存泄露分析
查看堆内存占用正常,jvm垃圾回收也没有异常.而top出来显示java占用内存是几个G,那么可能想到了是堆外内存泄漏. 需要安装google-perftools工具进行分析 1.先安装g++ 不然编译 ...
最新文章
- 服务器温度3d显示,智能问答助手、3D可视化展示,腾讯医典“黑科技”助力科普更有温度...
- python 使用UUID库生成唯一ID
- 莫队(不带修改)模板
- Java IO篇:什么是 Proactor 网络模型?
- VTK:相互作用之SelectAVertex
- 方法性能分析器--装饰者模式应用
- 理论基础 —— 排序 —— 快速排序
- 每天一个小异常——ssh整合空指针异常
- 突发!Java首度“落泪”,愿永久祝福Python!网友:我也想哭!
- 写作的积累 —— 台词
- vue 项目安装 (入门)
- 开源商城小程序源码(小程序商城完整版源码)附搭建部署教程
- 基于JSP实现的影视创作论坛系统
- c++编写浪漫烟花 表白代码大全
- 公众号吸粉实操之qq群吸粉
- 《Flutter入门疑难杂症》imagepicker ImagePicker().getVideo()返回.jpg
- 【嵌入式04】用寄存器HAL库完成LED流水灯程序
- TTL接口笔记本液晶屏改液晶显示器
- wazuh-monitord agent连接监控
- 【数据】2000-2020Landscan Global Population Database(全球人口分布数据集-1km)下载教程
热门文章
- Vue动态传值与接收步骤
- 定义软件定义的存储市场
- Codeforces Round #281 (Div. 2) A. Vasya and Football 模拟
- css中margin:0 auto没作用
- [PHP]基本排序(冒泡排序、快速排序、选择排序、插入排序、二分法排序)
- ArcEngine由点生成TIN
- Node.js Server
- Windows系统下,使用Emacs+Putty操作远程机器
- TP-Link发布网格路由器Deco M5
- 【bzoj2281】[Sdoi2011]黑白棋