【JVM】垃圾回收机制

1. 如何判断对象是否应该回收

引用计数法

Java中,引用和对象是有关联的,如果要操作对象则必须用引用进行。
因此,很显然有一个很简单的方法是通过引用计数来判断一个对象是否可以回收。简单来说就是给对象添加一个引用计数器,每当有一个地方引用他,计数器加一,每当一个引用失效,计数器减一。
任何时刻计数器值为零的对象就是不可能再被使用的,那么这个对象就是可回收对象。

那为什么主流的Java虚拟机里都没有使用这种算法呢?其中最主要的原因是他很难解决对象之间相互循环引用的问题

可达性分析(根搜索路径)

图片说明

哪些对象可以作为GC Roots呢

  • 虚拟机栈(栈帧中的局部变量表)中引用的对象;
  • 方法区中类静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中JNI(Native方法)引用的对象。

2. 内存分配策略

  • 对象优先在EDEN分配,如果EDEN区没有足够的空间进行分配,将会发起一次Minor GC;
  • 大对象直接进入老年代,例如很大的数组;
  • 长期存活的对象将进入老年代,默认活过15次gc;
  • 动态对象年龄判定,在survivor区空间中相同年龄所有对象的大小大于survivor区的一半,年龄大于或等于该年龄的对象直接进入老年区;
  • 空间分配担保,发生minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,如果这个条件成立,那么可以确保minor GC是安全的。如果担保失败,那么只好再失败后重新发起一次full GC。

3. 垃圾回收算法

  • 标记清除
  • 复制
  • 标记整理
  • 分代收集

图片说明

图片说明

图片说明

4. 垃圾收集器简单梳理

几种常用的垃圾收集器
图片说明

1. 串行垃圾回收器Serial

为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。因此不适合服务器环境使用。

2. 并行垃圾收集器

多个垃圾回收线程并行工作,此时用户线程是暂停的,适用于科学计算/大数据处理首台处理等弱交互场景。

3. CMS(并发标记清除)垃圾收集器

用户线程和垃圾收集线程同时执行(不一定是并行,可能是交替执行),不需要停顿用户线程,互联网公司多用他,适用于对响应时间有要求的场景。

以上三个小总结

图片说明

4. G1垃圾收集器

将堆内存分割为不同的region,使eden、survivor、老年代的内存不再连续,并发地进行收集。

5. 对垃圾收集器的理解

1. 怎么查看默认的垃圾收集器?

图片说明

2. 默认的垃圾收集器有哪些

图片说明

图片说明

图片说明

3. 部分参数预先说明

图片说明

4. Server/Client模式

图片说明

6. 新生代垃圾收集器

1. Serial

图片说明

图片说明

2. ParNew

图片说明

图片说明

3. Parallel Scanvenge (JAVA 8 默认)

图片说明

图片说明

图片说明

7. 老年代垃圾收集器

1. Parallel Old(Java 8 默认)

图片说明

2. CMS(自动关联ParNew)

图片说明
图片说明
图片说明

  • 初始标记:只是标记一下GC Roots能直接关联的对象,速度很快,会暂停所有工作线程。
  • 并发标记:进行GC Roots跟踪过程,和用户线程一起工作,不需要暂停工作线程。是主要的标记过程,会标记全部对象。
  • 重新标记:为了修正在并发标记期间,因用户程序继续运行而导致的标记产生变动的那一部分对象的标记记录,仍然需要暂停所有工作线程。(由于并发标记时,用户线程仍然在工作,因此正式清理前,再做修正)。
  • 并发清除:清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。基于标记结果,直接清理对象。(由于耗时最长的并发标记和并发清除过程中,垃圾收集线程和用户线程在一起工作,因此总体看来CMS的垃圾回收和用户线程是一起并发执行的)。

图片说明

  • 优点:并发收集低停顿
  • 缺点:
    • 对CPU资源压力大:由于并发进行,CMS在收集垃圾时与应用线程还是会增加对堆内存的占用,也就是说,CMS必须在老年代堆内存用尽之前完成垃圾回收。否则当CMS回收失败时,将触发担保机制,启动的Serial Old回收器将会以STW的方式进行一次GC,从而造成较大的停顿时间。
    • 标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩。CMS也提供了参数-XX:CMSFullGCsBeforeCompaction(默认0,即每次都进行内存整理)来制定多少次CMS手机之后进行一次压缩的Full GC。

3. Serial Old

图片说明

8. 垃圾收集器配置代码总结

图片说明

9. 如何选择垃圾收集器

图片说明

垃圾收集器之间的关联:
图片说明

10. 单独拎出来的G1

图片说明
图片说明
图片说明
图片说明
图片说明

1. 原理

区域化的垃圾收集器
图片说明
图片说明
图片说明
图片说明
图片说明

回收步骤
图片说明
图片说明
图片说明
图片说明

2. 参数

图片说明
图片说明
图片说明

3. 对比CMS

图片说明

全部评论

相关推荐

想干测开的tomca...:让我来压力你!!!: 这份简历看着“技术词堆得满”,实则是“虚胖没干货”,槽点一抓一大把: 1. **项目描述是“技术名词报菜名”,没半分自己的实际价值** 不管是IntelliDoc还是人人探店,全是堆Redis、Elasticsearch、RAG这些时髦词,但你到底干了啥?“基于Redis Bitmap管理分片”是你写了核心逻辑还是只调用了API?“QPS提升至1500”是你独立压测优化的,还是团队成果你蹭着写?全程没“我负责XX模块”“解决了XX具体问题”,纯把技术文档里的术语扒下来凑字数,看着像“知道名词但没实际动手”的实习生抄的。 2. **短项目塞满超纲技术点,可信度直接***** IntelliDoc就干了5个月,又是RAG又是大模型流式响应又是RBAC权限,这堆活儿正经团队分工干都得小半年,你一个后端开发5个月能吃透这么多?明显是把能想到的技术全往里面塞,生怕别人知道你实际只做了个文件上传——这种“技术堆砌式造假”,面试官一眼就能看出水分。 3. **技能栏是“模糊词混子集合”,没半点硬核度** “熟悉HashMap底层”“了解JVM内存模型”——“熟悉”是能手写扩容逻辑?“了解”是能排查GC问题?全是模棱两可的词,既没对应项目里的实践,也没体现深度,等于白写;项目里用了Elasticsearch的KNN检索,技能栏里提都没提具体掌握程度,明显是“用过但不懂”的硬凑。 4. **教育背景和自我评价全是“无效信息垃圾”** GPA前10%这么好的牌,只列“Java程序设计”这种基础课,分布式、微服务这些后端核心课提都不提,白瞎了专业优势;自我评价那堆“积极认真、细心负责”,是从招聘网站抄的模板吧?没有任何和项目挂钩的具体事例,比如“解决过XX bug”“优化过XX性能”,纯废话,看完等于没看。 总结:这简历是“技术名词缝合怪+自我感动式凑数”,看着像“背了后端技术栈名词的应届生”,实则没干货、没重点、没可信度——面试官扫30秒就会丢一边,因为连“你能干嘛”都没说清楚。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务