
你真的了解GC吗?
发布日期:2021-05-14 09:35:54
浏览次数:24
分类:精选文章
本文共 1196 字,大约阅读时间需要 3 分钟。
GC是什么?
垃圾回收(GC)在计算机科学中是一种自动化的内存管理机制。当某个程序占用的一部分内存空间不再被程序访问时,垃圾回收器会将这些内存空间归还给操作系统。这种机制能够减轻程序员的负担,并预防因内存泄漏导致的错误。GC的运行机制
垃圾回收需要知道哪些对象可以回收才能进行内存管理。判断对象内存是否能回收主要有以下两种方式:引用计数法
这种方法通过维护一个计数器来判断对象的引用次数。当计数器值为0时,该对象的内存可以回收。虽然引用计数法简单,但它无法处理循环依赖的情况(如上文所示的A、B、C对象引用循环)。可达性分析算法
JVM中使用可达性分析算法。 首先确认GC Root对象(如所存活的线程、方法区的静态对象、虚拟机栈中的局部变量表中的对象等)。然后通过分析这些根对象所引用的对象 chains,逐层分析这些对象是否被根对象所引用,最终确定哪些对象是可回收的。 虽然这个算法理论上是正确的,但在实际应用中,可能会因为被根对象间接引用而导致一些对象无法被回收,导致内存泄漏。因此,正确地理解哪些对象可以当作GC Root是非常重要的。GC回收内存
内存回收的具体方式主要有以下几种算法:标记清除算法
标记清除是最简单粗暴的算法,只需标记会被回收的内存区域,然后直接清除即可。优点是速度快,但缺点是内存碎片化严重,影响后续内存分配。复制算法
将内存空间分为两部分,只用其中一半进行存放。每次垃圾回收时,将活跃对象拷贝到另一半内存空间,原有的内存空间直接清除。虽然效率较高,但会浪费大量内存空间(将可用空间减半)。标记压缩算法
在标记完对象后,将存活的对象压缩到内存的一端,剩下的内存空间直接清除。这种方式可以显著减少内存碎片,但是需要频繁移动对象内存,性能消耗较大。分代算法
分代算法将内存分为新生代和老年代。新生代内存分为三个区段:Eden、Survivor0和Survivor1。在第一次Monitor GC(内存回收)时,Eden区存活的对象会被复制到Survivor0,并清理Eden区。第二次和第三次 Monitor GC 时,Eden和Survivor0的对象会被复制到Survivor1或Survivor0中。 超过一定次数的Monitor GC后(通常为15次),如果新生代内存还无法满足需求,则会将存活的对象复制到老年代中。老年代使用标记压缩算法回收内存。老年代内存到达阈值时则触发Full GC。此外,老年代中存在引用到新生代对象的情况也会导致内存回收困难,因此分代算法使用了card table记录老年代中的引用情况,以确保有针对性地进行内存清理。
特殊情况
老年代中的对象有时候可能直接或间接引用新生代的对象。为了避免这种情况造成的内存泄漏,需要避免在这些情况下创建无法被回收的对象引用。你的技术咨询小号:
关注更多技术文章,获取实用技能!发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月15日 04时14分01秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
注册页面案例
2019-03-11
np.bincount(x)的简单解释
2019-03-11
LeetCode Top-100 T22-括号生成
2019-03-11
vscode设置eslint保存文件时自动修复eslint错误
2019-03-11
JAVA 多线程
2019-03-11
Java的 arraylist类【具体案例】
2019-03-11
牛客-链表中环的入口节点(Java)
2019-03-11
解决微信小程序中 calc 失效问题
2019-03-11
堆的应用_topK算法和堆排序
2019-03-11
最大半连通子图
2019-03-11
Remove Extra one 维护前缀最大最小值
2019-03-11
跳台阶
2019-03-11
另类加法,走方格的方案数,最近公共祖先
2019-03-11
[Java Path Finder][JPF学习笔记][7]JPF输出详细程度设置
2019-03-11
GitHub完整记录数据库GHTorrent的下载和安装经验
2019-03-11
设计模式—— 三:依赖倒置原则
2019-03-11
SpringBoot打包之后乱码
2019-03-11
因SGA分配错误无法启动数据库
2019-03-11
Oracle修改字段类型方法总结
2019-03-11
ORA-00020 超过当前最大连接数
2019-03-11