【学习笔记】GC中的分代回收

5 篇文章 0 订阅
5 篇文章 0 订阅

GC为什么会导致应用程序卡顿?

GC线程导致工作线程停止,进而引发用户端出现卡顿现象

导致工作线程停止的机制叫做STW

首先理解GC线程与工作线程的关系

为了不产生垃圾回收时用户端的卡顿,最直观的方式是让GC线程与工作线程并行。而并行处理又会引发两个问题。

  1. 回收不彻底。GC开始时,不是垃圾(有引用),而GC结束时又变为垃圾(删除引用)
  2. 发生空指针异常。GC开始时是垃圾(还没被引用),当结束时又被使用(建立引用)

什么是STW

Stop the world。GC线程开启的同时暂停一切用户线程,造成卡顿

如何缓解

  1. 尽量减缓触发GC的次数
  2. 缩小GC范围
  3. 想办法让GC并行和并发

一些评价GC的指标

  1. 吞吐量:回收范围(堆)大小/GC总耗时
  2. 最大停顿耗时:最长STW时间
  3. 回收频率:回收的间隔时间频率,越低越好
  4. 响应时间:从一个实例成为垃圾,到他被释放的时间
  5. 空间利用率:堆中真正能够存储实例的空间占比

分代回收

  1. 老年代占堆的2/3,年轻代占1/3
  2. 新生区占年轻代的4/5
  3. 两个幸存区各占年轻代的1/10

每一个在内存中创建的实例,都有一个分代年龄。对象每经历一次GC,而没被回收,分代年龄会+1

新创建的实例会存放在新生区中,如果新生区空间不足,触发针对整个年轻代的youngGC,触发后会清除掉新生区的垃圾实例,并将非垃圾实例移植其中一个幸存区,重复触发youngGC,会让幸存区两个空间内的实例来回移动,并将所有年龄+1。

如果幸存区中实例相同年龄的总和,大于幸存区的一半时,这些对象就会进入到老年代,或者年龄大于 -XX:MaxTenuringThreshold,从幸存区进入老年代,默认15,参数可配置。

如果老年代空间不足,触发youngGC时,将转而触发针对整个堆的fullGC,清理所有区域内的垃圾对象

分代回收本质上是一种基于经验,得出的垃圾回收优化策略,包括:

  1. 绝大多数的实例,生命周期都很短
  2. 熬过越多次垃圾回收过程的实例,越难以消亡
  3. 跨代引用,相对于同代引用来说仅占极少数

优点:

  1. 能够筛选出生命周期不同的实例,让他们在不同时机被回收,避免每次都针对整个堆进行回收
  2. 让不同的代,可以选择合适自己的不同的垃圾回收算法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值