Java垃圾回收

目录

一、自动垃圾回收算法

1.引用计数法(Reference Counting)

2. 标记-清除(Mark and Sweep)

二、Java中的垃圾回收

1. 内存池的划分

 2.内存分配

Eden区

Survivor区

提升阈值

永久代

元数据区(Metaspace)

Minor GC / Major GC / Full GC

三、GC算法

1.标记可达对象(Mark)

2.删除不可达对象

1)清除

2)整理

复制

四、GC算法实现

1. Serial GC

2. Parallel GC

3. Concurrent Mark and Sweep(CMS)

CMS中Full GC的各个阶段

4. G1



一、自动垃圾回收算法

1.引用计数法(Reference Counting)

缺点:循环引用,导致红色部分引用计数一直大于零 ;

2. 标记-清除(Mark and Sweep)

 缺点:STW(Stop the World),需要暂停应用程序的所有线程;


二、Java中的垃圾回收

1. 内存池的划分

 2.内存分配

Eden区

1)大部分对象直接由JVM 在对应线程的TLAB(Thread Local Allocation Buffer,线程本地分配缓存区)中分配,避免与其他线程的同步操作。

2)如果 TLAB 中没有足够的内存空间,就会在共享Eden区之中分配。

3)如果共享Eden区也没有足够的空间,就会触发一次年轻代GC 来释放内存空间。

4)如果GC之后 Eden 区依然没有足够的空闲内存区域,则对象就会被分配到老年代空间。

Survivor区

1)from 和 to 区,任意时刻总有一个存活区是空的(empty),空的那个存活区,用于在下一次年轻代GC时存放收集的对象。

2)年轻代中所有的存活对象(包括Edenq区和非空的那个 “from” 存活区)都会被 复制 到 ”to“ 存活区。

3)存活的对象会在两个存活区之间复制多次,直到某些对象的存活 时间达到一定的阀值(提示场景1)会被提升到老年代。提升的时候,存活区的对象不再是复制到另一个存活区,而是 迁移 到老年代。

提升阈值

1)具体的提升阈值由JVM动态调整,但也可以用参数-XX:+MaxTenuringThreshold来指定上限。如果设置-XX:+MaxTenuringThreshold = 0 ,则GC时存活对象不在存活区之间复制,直接提升到老年代。

2)现代 JVM 中这个阈值默认设置为15个 GC周期,这也是HotSpot中的最大值。

3)如果存活区空间不够存放年轻代中的存活对象(提升场景2),提升也可能更早地进行。

永久代

1)在Java 8 之前有一个特殊的空间,称为“永久代”,这是存储元数据(metadata)的地方,比如 class 信息等。此外,这个区域中也保存有其他的数据和信息, 包括 内部化的字符串等等。

2)实际上这给Java开发者造成了很多麻烦,因为很难去计算这块区域到底需要占用多少内存空间,预测失败导致的结果就是产生 OOM。

元数据区(Metaspace)

1)Java 8直接删除了永久代(Permanent Generation),改用 Metaspace。Java 中很多杂七杂八的东西都放置到普通的堆内存里。

2)像类定义(class definitions)之类的信息会被加载到 Metaspace 中。元数据区位于本地内存(native memory),不再影响到普通的Java对象。默认情况下, Metaspace的大小只受限于 Java进程可用的本地内存。

Minor GC / Major GC / Full GC

Minor GC:回收年轻代的内存; 

major GC:回收的是老年代的内存;

Full GC:回收的是整个堆内存;


三、GC算法

1.标记可达对象(Mark)

2.删除不可达对象

1)清除

Mark and Sweep(标记-清除) 

缺点:

  • 内存碎片化(内存不连续,内存充足,但无法分配给超出连续内存大小的对象)
  • 维护空闲表 (需要用那个空闲表记录内存区域的位置和大小)

2)整理

Mark-Sweep-Compact(标记-清除-整理算法)

优点:

  • 内存连续;

缺点:

  • STW时间增加;

复制

Mark and Copy(标记-复制算法)

优点:

  • 内存连续;
  • 标记和复制可以同时进行;

缺点:

  • 内存使用率低;

四、GC算法实现

Java 8中各种组合的垃圾收集器

1. Serial GC

串行GC:

1)Serial GC 对年轻代使用标记-复制(Mark and Copy)算法, 对老年代使用 标记-清除-整理(Mark - Sweep - Compat)算法;

2)触发全线暂停(STW),停止所有的应用线程;

3)两者都是 单线程 的垃圾收集器,不能进行并行处理,不能充分利用多核CPU;

2. Parallel GC

并行GC

1)Parellel GC 对年轻代使用标记-复制(Mark and Copy)算法, 对老年代使用 标记-清除-整理(Mark - Sweep - Compat)算法;

2)触发STW事件,暂停所有的应用线程;

3)在执行 标记和 复制/整理阶段时都使用 多个线程 ;通过并行执行, 使得GC时间大幅减少;

3. Concurrent Mark and Sweep(CMS)

并发标记清除

1)CMS对年轻代采用并行标记-复制(Mark and Copy)算法,,对老年代主要使用并发标记-清除(Mark and Sweep)。

2)不对老年代进行整理, 而是使用空闲列表(free-lists)来管理内存空间的回收;

3)在老年代标记-清除(Mark and Sweep) 阶段的大部分工作和应用线程一起并发执行;

3)在这些阶段并没有明显的应用线程暂停,仍然和应用线程争抢CPU时间。默认情况下, CMS 使用的并发线程数等于CPU内核数的 1/4;

CMS中Full GC的各个阶段

1)初始标记( 需要STW )

标记老年代中, GC ROOT 的直接引用, 以及由年轻代中存活对象所引用的对象;

只标记GC ROOT和年轻代的直接引用对象,所以时间短;

2)并发标记

垃圾收集器遍历老年代, 标记所有的存活对象;

 “并发标记”阶段,不用暂停暂停应用程序。 

并非所有老年代中存活的对象都会被标记, 因为在标记过程中对象的引用关系还在发生变化。

3)并发预清理

与应用线程并行执行的, 不需要停止应用线程;

因为前一阶段是与程序并发进行的,可能有一些引用已经改变;

如果在并发标记过程中发生了引用关系变化,JVM会(通过“Card”)将发生了改变的区域标记为“脏”区(卡片标记);

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

 

4)并发可取消的预清理

与应用线程并行执行的, 不需要停止应用线程;

本阶段尝试在 STW 的 Final Remark 之前尽可能地多做一些工作;

本阶段的具体时间取决于多种因素,,因为它循环做同样的事情,直到满足某个退出条件( 如迭代次数, 有用工作量, 消耗的系统时间等等);

5)最终标记( 需要STW )

这是GC事件中第二次(也是最后一次)STW阶段;

目标是完成老年代中所有存活对象的标记;

因为之前的 preclean 阶段是并发的, 有可能无法跟上应用程序的变化速度,所以需要 STW暂停来处理复杂情况;

6)并发清除

与应用程序并发执行,不需要STW停顿;

基于标记结果,删除未使用的对象,并收回他们占用的空间;

 7)并发重置

与应用线程并行执行的, 不需要停止应用线程;

重置CMS算法相关的内部数据, 为下一次GC做准备;

4. G1

Garbage Fist(垃圾优先算法)

将STW停顿的时间和分布变成可预期以及可配置的。可以为其设置某项特定的性能指标,可以指定: 在任意 xx 毫秒的时间范围内, STW停顿不得超过 x 毫秒; Garbage-First GC 会尽力达成这个目标(有很大的概率会满足, 但并不完全确定,具体是多少将是硬实时的[hard real-time]);

1)堆不再分成连续的年轻代和老年代空间。而是划分为多个(通常是2048个)可以存放对象的 小堆区;每个小堆区都可能是 Eden区, Survivor区或者Old区。

2)GC不必每次都去收集整个堆空间, 而是以增量的方式来处理::每次只处理一部分小堆区,称为此次的回收集(collection set).;

G1 – Garbage First(垃圾优先算法) - 图1

3)每次暂停都会收集所有年轻代的小堆区, 但可能只包含一部分老年代小堆区;

4)G1的另一项创新, 是在并发阶段估算每个小堆区存活对象的总数;用来构建回收集(collection set)的原则是: 垃圾最多的小堆区会被优先收集(Garbage First)

G1 – Garbage First(垃圾优先算法) - 图2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值