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

相关推荐
言乐610 分钟前
Python实现关税自动计算模型
开发语言·python·django·virtualenv·pygame
朝朝辞暮i11 分钟前
C++ 第 14 课:引用 &
开发语言·c++·算法
光依旧13 分钟前
MCP实战手记(八):从“能跑“到“能上线“——无状态MCP Server的生产落地清单
java·人工智能·spring boot·架构·ai agent·mcp
Joe_Wang530 分钟前
【从0到1学习JVM · 21】既不浪费空间又没有碎片,标记整理算法到底慢在哪
jvm·学习·算法·垃圾回收·标记整理算法
梅雅达编程笔记39 分钟前
04-Python CSV数据保存与翻页抓取
开发语言·爬虫·python·pandas·数据采集·csv
C++ 老炮儿的技术栈1 小时前
有符号变量与无符号变量的区别
服务器·开发语言·前端·数据结构·c++·算法·c
估值探索者1 小时前
【Python量化策略实战 #04】Donchian 通道假突破太多?用 ATR 阈值过滤跑通真实突破信号
开发语言·python·接口·api接口·数据api接口·股票数据api接口
个 人 练 习 生1 小时前
C++:模板初阶详解
开发语言·c++·经验分享·学习
知识分享小能手1 小时前
C++ 学习教程,从入门到精通,C++类继承 — 完整知识点详解(13)
开发语言·c++·学习
弹简特1 小时前
【Java项目-企悦抽】15-活动管理模块02-活动创建测试与活动列表实现
java·开发语言·springboot