@程序员世杰: 彻底搞懂JVM垃圾回收 哈喽,大家好🎉,我是世杰。本文我为大家介绍面试官经常考察的「JVM垃圾回收那些事」面试连环call如何判断对象是否应被回收?finalize方法的实现机制是什么?如何判断类应该被回收?垃圾回收算法都有什么? 优缺点是什么?Minor GC, Major GC, Full GC 分别代表什么?JVM都有哪些内存分配策略?1. 对象回收判断1.1 引用计数算法「定义」一个对象被创建之后,系统会给这个对象初始化一个引用计数器,当这个对象被引用了,则计数器 +1,而当该引用失效后,计数器便 -1,直到计数器为 0,意味着该对象不再被使用了,则可以将其进行回收了。「存在问题」两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收。1.2 可达性分析算法「定义」以 GC Roots 作为起始点进行搜索,一步步遍历找到和这个根对象具有引用关系的对象,然后再从这些对象开始继续寻找,能够到达到的对象都是存活的,不可达的对象可被回收。在 Java 中 GC Roots 一般包含以下内容:虚拟机栈中引用的对象本地方法栈中引用的对象方法区中类静态属性引用的对象方法区中的常量引用的对象1.3 finalize()对象可以被回收,就代表一定会被回收吗?即使在可达性分析法中不可达的对象,也并不是立刻回收。宣告一个对象死亡,至少要经历两次标记「第一次标记」如果对象进行可达性分析算法之后发现未与 GC Roots 引用链相连,那它将会第一次标记并且进行一次筛选。当对象没有覆盖 finalize () 方法、或者 finalize () 方法已经被 JVM 执行过,则判定为可回收对象。如果对象有必要执行 finalize () 方法,则被放入 F-Queue 队列中。稍后在 JVM 自动建立、低优先级的 Finalizer 线程(可能多个线程)中触发这个方法.「第二次标记」GC 对 F-Queue 队列中的对象进行二次标记。如果对象在 finalize () 方法中重新与引用链上的任何一个对象建立了关联,那么二次标记时则会将它移出 “即将回收” 集合。如果此时对象还没成功逃脱,那么只能被回收了。注意 ⚠️:JDK9 版本及后续版本中各个类中的 finalize 方法会被逐渐弃用移除。忘掉它的存在吧!2. 类回收判断在大量使用反射、动态代理、CGLib 等 ByteCode 框架、动态生成 JSP 以及 OSGi 这类频繁自定义 ClassLoader 的场景都需要虚拟机具备类卸载功能,以保证不会出现内存溢出。JVM方法区存储的是类信息,因此主要针对方法区进行类回收,那么如何判断一个类是无用的类的呢?类需要同时满足下面 3 个条件才能算是 “无用的类”:该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。加载该类的 ClassLoader 已经被回收。该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。虚拟机可以对满足上述 3 个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用就会必然被回收。3. 垃圾回收算法3.1 标记-清除将存活的对象进行标记,然后清理掉未被标记的对象。这是一个非常基本的GC算法,它是现代GC算法的思想基础,分为标记和清除两个阶段:先把所有活动的对象标记(可达性分析法)出来,然后把没有被标记的对象统一清除掉。「不足」标记和清除过程效率都不高;会产生大量不连续的内存碎片,导致无法给大对象分配内存。3.2 标记-整理让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。标记—整理算法适用于存活对象较多的场合,它的标记阶段和标记-清除算法中的一样。整理阶段是将所有存活的对象压缩到内存的一端,之后清理边界外所有的空间。它的效率也不高。3.3 复制将内存划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了就将还存活的对象复制到另一块上面,然后再把使用过的内存空间进行一次清理。它比标记-清除算法要高效,但不适用于存活对象较多的内存,因为复制的时候会有较多的时间消耗。它的致命缺点是会有一半的内存浪费。现在的商业虚拟机都采用这种收集算法来回收新生代,但是并不是将新生代划分为大小相等的两块,而是分为一块较大的 Eden 空间和两块较小的 Survivor 空间,每次使用 Eden 空间和其中一块 Survivor。在回收时,将 Eden 和 Survivor 中还存活着的对象一次性复制到另一块 Survivor 空间上,最后清理 Eden 和使用过的那一块 Survivor。3.4 分代收集现在的商业虚拟机采用分代收集算法,它根据对象存活周期将内存划分为几块,不同块采用适当的收集算法。一般将堆分为新生代和老年代。新生代使用: 复制算法老年代使用: 标记-清除 或者 标记-整理 算法『新生代(Young Generation)』所有新生成的对象首先都是放在新生代的。新生代的目标就是尽可能快速的收集掉那些生命周期短的对象。新生代内存分配一块较大的 Eden 空间和两块较小的 Survivor 空间(默认 Eden 和 Survivor 的大小比例是 8:1)。每次使用 Eden 和其中一块 Survivor 空间(当Eden内存满了就会把对象分配到Survivor区)回收时将 Eden 和 Survivor 空间中存活的对象一次性复制到另一块 Survivor 空间上。最后清理掉 Eden 和使用过的 Survivor 空间。Survivor 区总有一个是空的。如果另一块 Survivor 空间没有足够内存来存放上一次新生代收集下来的存活对象,那么这些对象则直接进入老年代。新生代发生的GC也叫做Minor GC,MinorGC发生频率比较高(不一定等Eden区满了才触发)。『老年代(Old Generation)』在新生代中经历了 N 次垃圾回收后仍然存活的对象,就会被放到老年代中。因此,可以认为老年代中存放的都是一些生命周期较长的对象。内存比新生代也大很多(大概比例是1:2),当老年代内存满时触发 Major 或者 Full GC,发生频率比较低,老年代对象存活时间比较长,存活率标记高4. Minor GC、Major GC、Full GCMinor GC/Young GC:只是新生代的垃圾收集Major GC/Old GC:只是老年代的垃圾收集目前,只有 CMS GC 会有单独收集老年代的行为很多时候 Major GC 会和 Full GC 混合使用,需要具体分辨是老年代回收还是整堆回收Mixed GC:收集整个新生代以及部分老年代的垃圾收集目前只有 G1 GC 会有这种行为Full GC:收集整个 Java 堆和方法区的垃圾对于 Minor GC,其触发条件非常简单,当 Eden 空间满时,就将触发一次 Minor GC。而 Full GC 则相对复杂,有以下条件:调用 System.gc()老年代空间不足空间分配担保失败JDK 1.7 及以前的永久代空间不足Concurrent Mode Failure注意 ⚠️:Concurrent Mode Failure 是 CMS 特有行为,执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC。5. 内存分配策略JVM为对象分配内存时,会有一些分配策略保证更好的使用和回收对象5.1 对象优先在 Eden 分配大多数情况下,对象在新生代 Eden 区分配,当 Eden 区空间不够时,发起 Minor GC。5.2 大对象直接进入老年代大对象是指需要连续内存空间的对象,最典型的大对象是那种很长的字符串以及数组。经常出现大对象会提前触发垃圾收集以获取足够的连续空间分配给大对象。-XX:PretenureSizeThreshold,大于此值的对象直接在老年代分配,避免在 Eden 区和 Survivor 区之间的大量内存复制。5.3 长期存活的对象进入老年代为对象定义年龄计数器,对象在 Eden 出生并经过 Minor GC 依然存活,将移动到 Survivor 中,年龄就增加 1 岁,增加到一定年龄则移动到老年代中。-XX:MaxTenuringThreshold 用来定义年龄的阈值。5.4 动态对象年龄判定虚拟机并不是永远地要求对象的年龄必须达到 MaxTenuringThreshold 才能晋升老年代,如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 空间的一半,则年龄大于或等于该年龄的对象可以直接进入老年代,无需等到 MaxTenuringThreshold 中要求的年龄。5.5 空间分配担保在发生 Minor GC 之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果条件成立的话,那么 Minor GC 可以确认是安全的。空间分配担保是为了确保在 Minor GC 之前老年代本身还有容纳新生代所有对象的剩余空间。如果空间分配担保失败则会进行 Full GC参考文章Java 垃圾回收基础知识JVM垃圾回收详解(重点)JVM之垃圾回收机制(GC) 点赞 6 评论 0 全部评论 推荐最新楼层 暂无评论,快来抢首评~
相关推荐
01-26 10:41 海康威视_技术支持部_云存储开发工程师(准入职员工) 网易游戏内推 幸福三要素:吃、累、全 关于吃 网易作为互联网行业出名的猪厂,真的是有原因的!作为曾经的员工,不得不夸夸网易,第一个优点是有饭堂,第二个优点是饭堂真的太多好吃的,单单自选菜式,每顿就有十几种不同的菜可选,还有粥粉面、麻辣烫、汉堡薯条、铁板饭、健康餐……近乎完美地覆盖到不同口味的同事需求!此外,早餐和宵夜都是免费的!早餐样式也很多,好喜欢吃蜂蜜蛋糕、蛋挞和肠粉!!宵夜的话也有几种选择,但是得加班到点才能领取,一般是面包+水果+牛奶,也还阔以! 所以,如果入职网易一点也不用担心每天吃啥! 关于累 感到累才会有所获,个人感觉工作强度还是相对较大的,而且非常卷。除了刚入职的一段时间,后面基本上每天都要... 网易游戏公司福利 601人发布 点赞 评论 收藏 分享 01-30 17:29 郑州大学 测试开发 测试开发简历求拷打 在学校还是太摆了,感觉简历都找不到什么写的,打算从下周一开始投,冲刺一下大厂。麻烦各位路过的牛友看看,拷打下简历 点赞 评论 收藏 分享 01-07 09:54 广东工业大学 后端工程师 27鼠鼠求简历优化 投了好多都打不合适 牛爷爷们求指点 行云流水1971:优化后简历(以 “后端开发岗” 为目标)
基本信息
姓名:XXX | 电话:XXX | 邮箱:XXX
求职意向:后端开发工程师 | 意向城市:XXX
教育经历
2023.09-2027.07 XX 大学 | 计算机科学与技术 | 本科
核心课程:Java 程序设计、数据库原理、计算机网络、数据结构(成绩均 85+)
技能关联:掌握 Java 基础语法、MySQL 增删改查,为后端开发奠定技术基础
项目经历
项目 1:小说推荐 - 大数据智能推荐平台 | 后端开发 | 2025.09-2025.12
技术栈:Java、SpringBoot、MySQL、Redis、Kafka
核心动作:
参与用户行为数据采集模块开发,用 Kafka 实现日志数据异步传输,峰值吞吐量提升 40%;
基于 MySQL 设计用户 - 小说关联表,配合 Redis 缓存热门推荐列表,页面响应时长从 300ms 缩短至 120ms;
成果:支撑日均 1000 + 用户访问,推荐内容点击率较初始版本提升 25%。
项目 2:在线博客 - 个性化博客分享平台 | 后端开发 | 2025.03-2025.06
技术栈:Java、SpringBoot、MyBatis、MySQL
核心动作:
开发博客发布 / 编辑接口,通过 MyBatis 实现数据持久化,接口成功率达 99.8%;
设计用户权限控制逻辑,区分普通用户 / 管理员操作权限,避免非法内容发布;
成果:完成 5 个核心功能模块开发,实现博客内容的全流程管理。
技能证书
技术栈:熟练使用 Java、SpringBoot、MyBatis 进行后端开发;掌握 MySQL 数据库设计与优化、Redis 缓存应用
工具:Git 版本管理、Postman 接口测试
自我评价
具备 Java 后端开发基础,参与 2 个完整项目的后端模块开发,能独立完成接口编写、数据持久化等工作;熟悉 SpringBoot 等主流框架,可快速上手企业级开发流程,具备良好的代码规范与逻辑思维。
需要我帮你补充项目的量化成果细节(比如接口性能、用户数据等)吗?若需要更精准的岗位适配优化,可私信沟通。 点赞 评论 收藏 分享 2025-12-25 22:05 门头沟学院 Java 提前实习有个蛋的好处 说真的,提前实习在我这完全没半点好处,反而把毕业前的快乐时光全搅和了!本来拿到 offer 后,明明可以好好享受最后一段无忧无虑的校园生活,跟朋友聚餐、旅行、好好放松,结果现在提前实习的风气越来越浓,逼着人早早去公司当社畜,提前体验那种朝九晚五、被工作追着跑的日子 —— 毕竟这种生活以后要过几十年,真没必要提前透支!反而我觉得,不打算转正的实习才是真・爽局!不用顾忌 “表现不好影响转正”,不用硬扛着做不喜欢的活,也不用小心翼翼看领导脸色,觉得工作没意思、学不到东西,或者单纯不想干了,随时能拍屁股走人,主打一个 “老子不转正,谁也管不着” 的自由。这种没有心理负担的实习,才不用把自己逼得紧绷,反而能更真实地感受工作氛围,合得来就多干阵子,合不来就及时抽身,比提前实习硬熬舒服多了! 喵_coding:难绷你这条上面给我推送个提前实习是你最大的优势 一人说一个提前实习的好处 点赞 评论 收藏 分享 01-28 23:05 莉莉丝游戏_2026届校招HRBP(准入职员工) 莉莉丝游戏内推,莉莉丝游戏内推码 【高工资和高福利】 🔸实习薪资本250/d,研300/d统一;校招社招薪资也很有竞争力 🔸Manner员工内购减10,自带杯再减5,能白嫖大多数饮品;新人入职day全天manner畅饮不限杯数(实习生入职也算,所以有新员工入职全部门可蹭 🔸有一整栋楼用来休闲娱乐,酒吧、猫屋、健身房、影音室、游泳馆、电竞房应有尽有,条件比市面大部分场所还好(所以员工是真的周末会来公司玩) 🔸每层配备卫生巾、常见药品,行政部门更换及时;超绝办公环境,升降桌、MacBookpro、人体工学椅是标配 🔸有班车从地铁到公司楼下(其实走过去也不远 【友好的企业文化】 🔸#莉莉丝游戏 企业文化是“简单真诚”,工... 莉莉丝游戏公司福利 541人发布 点赞 评论 收藏 分享 评论 点赞成功,聊一聊 >点赞 收藏 分享 评论