java进阶-优化GC垃圾回收机制

1.1什么是垃圾回收机制?

在程序运行期间,用来回收堆内产生了很多对象却不在使用的"垃圾"。让堆内的空闲空间更大

1.2垃圾回收机制执行过程中需要识别哪些对象是不使用的、在合适的时机去清除、用合适的算法去清除。

识别不再使用对象的方法

1、引用计数法:给每个对象一个计数器,有引用就+1,引用失效就-1,当计数器为0的时候,就是表示不再使用的对象;该方法优点是简单,缺点是不是满足以上条件就是代表废对象,比如对象a引用对象b,对象b引用对象a,两个计数都为1,但是两者都不被任何一个对象引用,却无法收回

2、可达性分析法:通过一系列GC-ROOT(根对象)为起点,线下开始搜索,走过的路径叫引用链,如果一个GC-ROOT没有任何引用链相连,则代表是废对象,可以回收

GC-ROOTS包含:

方法区中静态属性引用的对象、常量引用的对象、本地方法栈引用的对象、活跃的线程、虚拟机栈中引用的对象。

在合适的时机清除垃圾

GC不是一直在工作,它是有自己的触发条件的,主要是两类:一类是创建的对象充满了新生代堆频率快,速度快;第二类是老年代被充满时,频率低,速度慢,会导致STW。

用合适的算法去清除

1、标记-清除算法:先标记所有要回收的对象,再统一清除所有被标记的对象;优点是算法简单,缺点是标记和清除过程效率不高;在清除的时候会产生大量碎片

2、复制算法:将内存容量划分为大小相等的两块,每次只使用其中一块。当这一块用完了,就将还活着的对象复制到另外一块,然后把已经使用过的空间内存一次性清理掉;优点是实现简单运行效率高,没有内存碎片;缺点是可用内存缩小为原来的一半,浪费有点多,用于新生代多一点。

3、标记-整理算法:标记过程与标记-清除算法一样,但不直接清理,而是让所有存活的对象都向一端移去,然后直接清除掉端边界以外的内存。优点是没有内存碎片,缺点是移动对象成本相对较高。

4、分代收集法(JVM实际采用):该算法是把内存分为几个区域,每个区域使用最适合的算法。

1.3垃圾回收机制的代价(STW)

定义:当进行垃圾回收的时候,除了垃圾线程之外,其他的工作线程都被暂停掉。

影响:STW的长短直接影响到程序的响应速度

优化STW

方式1:分代收集-缩小STW的范围:JVM把内存分为新生代和老年代,避免每次GC都扫描整个堆,使扫描新生代的频率高,减少STW。

方式2:并行收集-加速STW的过程:在STW干活期间,启动多个GC线程工作,减少STW时间时间,代价是需要多核cpu,线程切换有开销,使用于追求高吞吐量的后台计算任务,可接受短暂的STW.

方式3:并发标记-让STW几乎消失:GC线程和应用程序线程尽量同时进行。

方式4:增量收集--化整为零:不再一次要求一次性回收整个新生代或老年代,G1把整个堆划分为诸多小块。它每一次只选一部分垃圾最多的小块进行回收;代价:回收的吞吐量可能会有点下降,但停顿时间变得可控且可预测。

方式5:无停顿收集器

通过指针染色、读屏障、染色指针等先进技术,使得绝大多数垃圾回收阶段都能于应用线程并发进行,甚至连对象移动都可以并发进行;代价实现复杂,对cpu有一定额外开销。

1.4在实际中如何减少STW

1、合理设置堆大小:太小容易触发GC,太大容易使STW时间增加;原则需要找到平衡点,根据业务特性调整。一般建议不超过32G(G1)。

2、调整新生代和老年代比例

如果业务中临时对象非常多,适合增大新生代,让这些对象在Min GC中快速消亡,避免过早进去老年代引发full GC,

3、设置大对象阈值

如果程序经常创建大对象(大数组),可以设置这个参数,让大对象直接进入老年代,避免Edent区和Surivivor区之间复制产生大量内存拷贝开销

4、选择合适的GC收集器

响应速度优先(低延迟):web应用、游戏服务器、交易系统->选择(G1)JDK9默认,CMS(jdk常用,或ZGC。

吞吐量优先(高计算):后台数据分析、科学计算-->选择ParallelGC(JDK8默认)

5、使用CMS时候预防碎片化

6、代码层面优化

避免在频繁调用的方法中创建大量临时对象,减少GC压力;合理使用对象池,服用对象,避免频繁创建和销毁;注意显式调用System.gc:会触发FullGC

相关推荐
Scott9999HH7 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔7 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海8 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
马优晨9 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区11 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大12 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai12 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说12 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json