您的位置:首页 > 其它

JVM垃圾收集机制

2017-12-27 19:07 381 查看

JVM垃圾收集机制

JVM结构



如何判定对象可回收

引用计数

缺点

很难解决对象之间循环引用的问题

可达性分析(根节点枚举)

使用引用链和GC Roots

GC停顿原因

根节点枚举时必须保证对象引用关闭保持不变,所以必须停顿所有java线程

可以作为GC Roots的对象

虚拟机栈(栈帧中的本地变量表)中引用的对象

方法区中类静态属性引用的对象

方法区中常量引用的对象

本地方法栈中JNI(即一般说的Native方法)引用的对象

垃圾收集算法

标记-清除算法

算法

标记需要回收的对象,标记完后统一清除

缺点

标记清除的过程效率不高

容易发生内存碎片

复制算法

算法

将内存分为两个相同大小的块,每次只使用其中一块,当一块用完时就将存活的对象复制到另一块,然后清空已用过的那块

缺点

将内存缩小为原来的一半

如果对象存活率较高时,会发生大量的复制

使用场景

常使用回收新生代内存,HotSpot实现方式,将新生代内存分为:一块较大的Eden空间和两个较小的Survivor空间。每次使用Eden和其中一个Survivor空间,内存回收时将存活对象复制到另一个Survivor空间,如果另一个Survivor空间不够,则将存活对象复制到老年代。默认Eden空间和Survivor空间比例为8:1。

标记-整理算法

算法

将存活的对象向一端移动,直接清理掉端边缘以为的内存

使用场景

常使用与清理老年代内存

垃圾收集器

Serial收集器



特点

单线程

简单

对于单个CPU来说没有线程交互开销

缺点

执行垃圾回收时需要停掉所有用户线程

使用算法

新生代使用复制算法

老年代使用标记-整理算法

PerNew收集器



特点

使用多线程进行垃圾收集,默认线程数量等于CPU的数量

常用于server模式下新生代的垃圾收集

为了降低gc停顿时间

Parallel Scavenge收集器

特点

新生代垃圾收集器,使用复制算法,且多线程收集垃圾

为了达到一个可控的吞吐量, 吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)

高的吞吐可以高效利用CPU时间,停顿时间越短,吞吐量越大

Serial Old收集器

特定

Serial Old收集器是 Serial收集器的老年带版本

单线程,使用“标记整理”算法

用途

与Parallel Scavenge收集器搭配使用

作为CMS收集器的后备预案,在并发收集器发现Concurrent Mode Failure时使用

Parallel Old收集器

特点

Parallel Scavenge收集器的老年代版本

使用标记-整理算法

CMS收集器



特点

为获取最短回收停顿时间为目标的收集器

步骤

初始标记

标记GC Roots关联的对象,速度很快,需要停止用户线程

并发标记

重新标记

并发清除

缺点

CMS收集器对CPU资源比较敏感

CMS收集器无法出炉浮动垃圾。浮动垃圾:CMS并发清理阶段用户线程还在运行,伴随程序的运行还会产生新的垃圾,这部分垃圾出现在标记过程之后,CMS无法再当次收集中处理掉它们。

CMS是基于标记-清除算法的收集器,会产生内存碎片。

G1收集器





特定

并行与并发

分代收集

空间整合(整理来看:标记-整理算法,局部来看:复制)

可预测的停顿

降低停顿时间

建立可预测的停顿时间模型

步骤

初始标记

stop the world(用户线程需要停止)

标记GC Roots能直接关联的对象

并发标记

从GC Roots开始对堆中的对象进行可达性分析,找出存活对象

与用户线程一起运行,此阶段比较耗时

最终标记

stop the world(用户线程需要停止)

修正并发标记期间因用户线程运行而导致标记产生变动的对象的标记记录

筛选回收

对各个Region的回收价值和成本进行排序

根据用户期望的GC停顿时间制订回收计划

优点

G1在回收内存后会马上同时做合并空闲内存的工作、而CMS默认是在STW(stop the world)的时候做

G1可以通过设置预期停顿时间(Pause Time)来控制垃圾收集时间避免

G1通过将内存空间分成区域(Region)的方式避免内存碎片问题

JVM配置信息

查看JVM配置

java -XX:+PrintCommandLineFlags -version


输入结果:

-XX:InitialHeapSize=2113761600 -XX:MaxHeapSize=32125009104 -XX:+PrintCommandLineFlags -XX:+UseCompressedOops -XX:+UseParallelGC
java version "1.7.0_55"
Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode)


修改JVM配置

JAVA_OPTS="-XX:+UseG1GC  -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:../logs/gc.log"


JVM常用参数

NewRatio


新生代
(Eden+2*Survivor)
和老年代的比例(不包含永久代)

例如
NewRatio=2
新生代:老年代=1:2 ,即新生代占对内存的 1/3

SurvivorRatio


两个SurvivorRatio和Eden的比

例如
SurvivorRatio=8
,两个SurvivorRatio:Eden=2:8,即SurvivorRatio占年轻代的1/10

UseParNewGC


打开此开关后,使用ParNew + Serial Old的收集器组合进行内存回收

UseConcMarkSweepGC


打开此开关后,使用ParNew + CMS + Serial Old的收集器组合进行内存回收。Serial Old作为CMS出现Concurrent Mode Failure失败后的后备收集器使用

UseParallelGC


虚拟机运行在Server模式下的默认值,打开此开关后,使用Parallel Scanvenge + Serial Old (PS MarkSweep)的收集器组合进行内存回收

UseG1GC


使用G1收集器

Hotspot堆内存结构



常见内存溢出问题

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded


参考资料

How is the default java heap size determined?

Garbage Collector Ergonomics

The Parallel Collector

Understanding GC pauses in JVM, HotSpot’s minor GC

Minor GC vs Major GC vs Full GC

Understanding Java Garbage Collection

Java Garbage Collection Basics

Getting Started with the G1 Garbage Collector

垃圾收集器与内存分配策略

java-performance-optimization

Understanding G1 GC Logs
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: