JVM中GC原理解析

JVM中GC原理解析

1.1什么是GC

GC可以理解为在追踪仍然使用的所有对象,并将其余对象标记为垃圾然后进行回收,这样的一个过程称之为GC,所有的GC系统可以从如下几个方面进行实现

1.GC判断策略(例如引用计数,对象可达)

2.GC收集算法(标记清除法,标记清除整理法,标记复制清除法,分带法)

3.GC收集器(例如Serial,Parallel,CMS,G1)


1.3手动GC

什么是手动GC呢?即是手动为对象分配内存并回收内存

如下这是一个简单的手动内存管理C编写的示例

int send_request() {

size_t n = read_size();

int *elements = malloc(n * sizeof(int));


if(read_elements(n, elements) < n) {

// elements not freed!

return -1;

}

// …

free(elements)

return 0;

}

手动GC忘记释放内存是常有的事情。这样的话会直接导致内存泄露。

1.4自动GC

什么是自动GC呢?

自动GC一般是由系统自动对内存进行管理

引用计数法

JVM中GC原理解析

其中:

1、绿色云表示它们指向的对象仍然由程序员使用。

2、蓝色圆圈是内存中的活动对象,其中的数字表示其引用计数

3、灰色圆圈是未从任何明确使用的对象引用的对象

对于引用计数法,有一个很大的缺陷就是循环引用,例如:

JVM中GC原理解析

其中红色对象实际上是应用程序不使用的垃圾。但是由于引用计数的限制,它们不符合垃圾回收原理,所以仍然存在内存中,导致内存泄露。

标记清除法

标记清除通常有两个步骤:

1.标记正在遍历所有可达的对象

2.清除不可达对象占用的内存地址

JVM中GC原理解析

这种方法就完美解决了对象之间循环依赖的问题,但是存在短时间的线程暂停。

二、JAVA中的GC分析

2.1、碎片与压缩

JVM在垃圾回收过程中可能会产生大量碎片,为了提供其读写性能,需要对碎片进行压缩

例如:

JVM中GC原理解析

2.2、分代设想

我们知道垃圾收集要停止应用程序的运行,那么如果这个收集过程需要的时间很长,就会对应用程序产生很大的性能问题,如何解决这个问题呢?通过实验发现内存中的对象可以将其分为两大类:

1.存活时间较短(这样的对象比较大)

2.存活时间较长(这样的对象量比较小)

基于对如上问题的分析,通过了解科学家提出了分代回收思路(年轻代,老年代,永久代),同时缩小垃圾回收范围。

例如:

JVM中GC原理解析

2.3、GC模式分析

垃圾收集事件(Garbage Collection events)通常分为:

1.Minor GC (小型GC):年轻代GC事件

2.Major GC(大型GC):老年代GC事件

3.Full GC (完全GC):整个堆的GC事件

三.GC算法基础

3.1、标记可达对象

现在的GC算法基本都是要从标记可达对象开始(Marking Reachable Objects)

例如:

JVM中GC原理解析

GC一般会设置一些特定对象为GC的根对象,例如:

1.栈中的变量

2.常量池中的引用

.....

GC基于根对象标记可访问对象(蓝色表示),对于不可达对象GC会认为是垃圾回收对象。

3.2、移除不可达对象

移除不可达对象(Removing Unused Objects)时会因GC算法的不同而不同,但是所有的GC操作一般都可以分为三组:清除(Sweep),压缩(Compact),复制(Copy)

清除(Sweep)

JVM中GC原理解析

压缩(Compact)

JVM中GC原理解析

复制(Copy)

JVM中GC原理解析

复制算法会基于标记清除压缩算法,创建新的内存空间用于存储幸存对象,同时可以复制与标记同时并发执行。这样可以较少GC时系统的暂停时间,提高系统性能

四、GC算法实现

现在对于JVM中的GC算法两大类:一类负责收集年轻代,一类负责收集老年代。假如没有显式指定垃圾回收算法,一般会采用系统平台默认算法,当然也可以自己指定,下面是JDK8中的一些垃圾回收算法应用组合如下:

Young

Tenured

JVM options

Serial

Serial

-XX:+UseSerialGC

Parallel Scavenge

Parallel Old

-XX:+UseParallelGC -XX:+UseParallelOldGC

Parallel New

CMS

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

G1

-XX:+UseG1GC

以上四种GC组合是现阶段最突出的几种方式。

4.1、Serial GC

Serial GC(串行收集器)应用特点:

1.内部只使用一个线程去回收(不能充分利用CPU的多核特性),无法并行化

2.GC过程可能会产生较长的时间停顿

3.Serial GC(串行收集器)算法应用:

3.1 新生代复制算法(新生代存活对象较少)

3.2 老年代标记-压缩算法(老年代对象回收较少,容易产生碎片)

Serial GC(串行收集器)场景应用:

a.应用在具体几百兆字节大小的JVM

b.应用在知有单个CPU的环境中

Serial GC(串行收集器)应用参数实践:

java -xx:+UseSerialGC com.mypackages.MyExecutableClass

Serial GC模式分析:

1.Minor GC

JVM中GC原理解析

2.Full GC

JVM中GC原理解析

4.2、Parallel GC

并行收集器应用特点:

1.可利用cpu的多核特性,可并行化执行GC操作。

2.在GC期间,所有cpu内核都在并行清理垃圾,所以暂停时间较短。


Parallel GC (并行收集器)算法应用:

1.在年轻代使用 标记-复制(mark-copy)算法:

1.在老年代使用 标记清除整理(mark-sweep-compact)算法


Parallel GC(并行收集器)场景应用:

1.应用于多核处理器,执行并行收集提高吞吐量。

2.GC操作仍需暂停应用程序,所以不适合低延迟场景


Parallel GC(并行收集器)模式分析:(事件分析)

1.Minor GC

JVM中GC原理解析

2.Full GC

JVM中GC原理解析

4.3、Concurrent Mark and Sweep (CMS)

即 标记-清除-垃圾收集器

CMS收集器特点:(避免在老年代垃圾收集时出现长时间卡顿)

1.使用空闲列表管理内存空间的回收,不对老年代进行整理

2在标记-清除阶段大部分工作和应用线程一起并发执行。


CMS算法应用:

1.年轻代采用并行STW方式的mark-copy(标记-复制)算法

2老年代主要使用并发 mark-sweep(标记-清除)算法。


CMS场景应用

1.应用于多核处理器,目标降低延迟,缩短停顿时间

2.cpu受限场景下,会与应用线程竞争cpu,吞吐量会减少


CMS关键阶段可以分为4个步骤:

1.初始标记 (CMS initial mark)

2.并发标记 ( CMS concurrent mark)

3.重新标记 ( CMS remark)

4.并发清除 (CMS concurrent sweep)

其中初始标记,重新标记这连个步骤仍然需要 "Stop The World" 初始标记仅仅只是标记GC Roots或yong gen能够直接关联到的对象,速度很快。

JVM中GC原理解析

并发标记阶段就是进行GC Roots Tracin的过程,在此阶段,垃圾收集器遍历老年代,标记所有的存活对象,从前一阶段InitialMark找到的root根开始算起。

JVM中GC原理解析

并发预清理(重新标记)阶段则是为了修正并发标记期间,因用户程序继续运作而导致冰机产生变动的那一部分的标记记录,这个阶段的停顿时间一般会比初始标记阶段长一些,但远比并发标记时间短。

JVM中GC原理解析

在预清理阶段,这些脏对象会被统计出来,从他们可达对象也被标记下来,此阶段完成后,用标记的card也就会被清空。

JVM中GC原理解析

并发清除此阶段与应用程序并发执行,不需要STW停顿。目的是删除未使用的对象,并回收他们占用的空间

JVM中GC原理解析

由于整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,所以总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行

私信666领取资料

展开阅读全文

页面更新:2024-04-29

标签:多核   线程   算法   标记   原理   对象   内存   垃圾   年代   阶段   时间

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top