自动内存管理机制-3.垃圾收集器与内存分配策略

本文详细解析了Java垃圾回收的基本原理,包括对象死亡的判断、垃圾收集算法、HotSpot虚拟机的具体实现,以及各种垃圾收集器的特点和应用场景。同时,文章还探讨了内存分配与回收策略,帮助读者全面掌握Java内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1确定对象是否死亡

1.1引用计数法

1.2可达性分析算法

1.3再谈引用

1.4对象死亡过程与拯救

1.5回收方法区

2垃圾收集算法

2.1标记-清除算法

2.2复制算法(新生代)

2.3标记整理算法(老年代)

3HotSpot的算法实现

3.1枚举根节点

3.2安全点

3.3安全区域

3.4记忆集与卡表

3.5写屏障

3.6并发的可达性分析

4垃圾收集器

4.1Serial收集器(新生代单线程)

4.2ParNew收集器(新生代并行)

4.3Parallel Scavenge收集器(新生代,可控制吞吐量)

4.4Serial Old收集器(单线程老年代)

4.5Parallel Old收集器(并行老年代)

4.6CMS收集器(并发标记清除,老年代,低停顿)

4.6.1三个明显缺点:

4.7G1收集器

简介

难点

运行过程

缺点

4.8低延迟收集器

概述

并发整理算法的实现

染色指针

优势

阶段 

优缺点

4.8理解GC日志

4.9垃圾收集器参数总结

5内存分配回收策略

5.1对象优先在Eden分配

5.1.1Minor GC与Full GC分别在什么时候发生

5.2大对象

5.3长期存活的对象进入老年代

5.4动态对象年龄判定

5.5空间分配担保


1确定对象是否死亡

1.1引用计数法

给对象添加一个引用计数器,被引用时+1,引用失效-1,为0时确定对象不再被使用

缺点:

很难解决循环引用

1.2可达性分析算法

1.3再谈引用

1.4对象死亡过程与拯救

对象死亡需要经历两次标记过程:

  • 第一次标记:

对象经过可达性分析后发现没有与GC Roots相连接的引用链,会被第一次标记和筛选。

筛选条件:对象覆盖了finalize()方法且finalize()方法未被虚拟机调用

经过筛选后会被放置在F-Queue队列,并在稍后被Finalizer线程执行。

  • 第二次标记:

如果对象在finalize()方法中拯救自己(重新与引用链上的任何一个对象建立关联),第二次标记时将被移除,否则面临被回收。

实际中避免finalize()方法使用。

1.5回收方法区

Java虚拟机规范不要求在方法区实现垃圾收集。

 

2垃圾收集算法

分代收集理论

2.1标记-清除算法

  • 不足:

标记和清除效率都不高

内存碎片

2.2复制算法(新生代)

每次用一半

  • 缺点:

在对象存活率高时要进行较多复制操作,效率变低

需要担保

老年代不采用这种算法

2.3标记整理算法(老年代)

先移动,再清理

3HotSpot的算法实现

3.1枚举根节点

可达性分析会消耗很多时间

且要在一致性的快照中进行,导致GC进行时必须停顿所有Java执行线程(STW

3.2安全点

https://cloud.tencent.com/developer/news/605800

程序执行至Safepoint(安全点)才能暂停执行GC

Safepoint以“让程序长时间执行”为标准选定,例如方法调用、循环跳转、异常跳转

抢占式中断:GC发生时中断所有线程,若线程不在安全点恢复,使其继续运行至安全点

主动中断:设置标志,线程主动轮询

3.3安全区域

程序不执行时(未分配CPU时间,sleep或blocked),无法执行至安全点

3.4记忆集与卡表

3.5写屏障

3.6并发的可达性分析

4垃圾收集器

4.1Serial收集器(新生代单线程)

单线程,且要暂停工作线程

用于client模式

4.2ParNew收集器(新生代并行)

多线程版本Serial收集器

能与CMS配合

 

4.3Parallel Scavenge收集器(新生代,可控制吞吐量)

与ParNew区别:

关注点不同。其他收集器关注缩短用户线程停顿时间(提高响应速度,用于与用户交互的程序),Parallel Scavenge关注吞吐量(尽快运算完,适合后台)

4.4Serial Old收集器(单线程老年代)

4.5Parallel Old收集器(并行老年代)

4.6CMS收集器(并发标记清除,老年代,低停顿)

Concurrent Mark Sweep

注重回收停顿,用于B/S系统服务端

优点:并发,低停顿

4.6.1三个明显缺点:

老年代需要预留空间保存用户线程产生的浮动垃圾

标记清除算法产生的碎片,内存整理无法并发执行

4.7G1收集器

简介

难点

运行过程

缺点

4.8低延迟收集器

概述

并发整理算法的实现

染色指针

优势

阶段 

优缺点

 

 

4.9理解GC日志

4.9.1jdk9之前

-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs

 

参考https://blog.youkuaiyun.com/yxc135/article/details/12137663

4.9.2jdk9

4.10垃圾收集器参数总结

 

/usr/java/jdk-11-qa/bin/java \
-XX:MaxDirectMemorySize=35g \
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xmx70g -Xms70g -XX:ParallelGCThreads=16 -XX:ConcGCThreads=4 \
-Xlog:gc*:/home/work/log/xxx/gc.log:time,level,tags,tid \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.port=xxxxx \
-Dcom.sun.management.jmxremote.host=127.0.0.1 \
-Djava.rmi.server.hostname=127.0.0.1 \
-jar /home/work/bin/xxx/xxx-server.jar

5内存分配回收策略

5.1对象优先在Eden分配

5.1.1Minor GC与Full GC分别在什么时候发生

Minor GC与Full GC分别在什么时候发生?

5.2大对象

5.3长期存活的对象进入老年代

5.4动态对象年龄判定

5.5空间分配担保

在发生Minor GC之前,虚拟机会检测 : 老年代最大可用的连续空间>新生代所有对象总空间?

满足,Minor GC是安全的,可以进行Minor GC。

不满足,虚拟机查看HandlePromotionFailure参数:

(1)为true,允许担保失败,会继续检测老年代最大可用的连续空间>历次晋升到老年代对象的平均大小。

若大于,将尝试进行一次minor gc。若小于,则重新进行一次full gc。

(2)为false,则不允许冒险,要进行full gc(对老年代进行gc)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值