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


title: jvm垃圾收集器与内存分配策略
date: 2017-12-13 23:56:27
tags: jvm
categories: jvm

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

垃圾回收算法

引用计数算法:

给对象添加一个引用计数器,每当有一个地方引用时就加1,当引用失效就减1。当引用为0时会被回收。

可达性分析算法:

通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路作为引用链,当一个对象没有任何引用链相联,则该对象不可达,即为可回收的对象。

GC-Roots包括:

  • 虚拟机栈(栈帧中本地变量表)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中JNI(一般为Native方法)引用的对象
标记-清除算法:

首先标记所有需要回收的对象,在标记完成后统一回收所有被标记的对象

不足之处:

  1. 标记和清除两个过程效率都不高
  2. 结束后会产生大量碎片
复制算法:

把内存划分为大小相等的两块,每次使用其中一块,使用的那块发生GC时将存活的对象复制到另一块,每次只对一个半区进行回收。

不足:将内存缩小为原来的一半,浪费空间

标记-整理算法:

标记过程与“标记-清除算法”相同,然后将对象碎片都向一边移动,合成一个整体

再谈引用

强引用:

普遍存在,即Object obj = new Object(); 只要强引用还在对象就不会被回收

软引用:

描述一些有用但却非必需的对象,在发生内存溢出异常之前会被回收。

弱引用:

描述非必需对象,比软引用弱一些,在发生GC之前会被回收。

虚引用:

最弱的引用,对于对象的生存周期无影响,也无法通过虚引用来获得对象实例。只是在对象被回收时会收到通知。

垃圾收集器

Serial收集器

单线程收集器,在GC时需要STW,即“Stop The World”暂停其他所有工作线程。缺点显而易见,停顿长体验差。唯一的优点是没有多余的线程开销,最高的单线程收集效率,对于分配内存较小的桌面应用(Client)停顿一般控制在几十毫秒,这是一个很好的选择。

ParNew收集器

Serial的多线程版本,是许多运行在server模式下jvm首选的新生代收集器,而且除了Serial只有ParNew能与CMS收集器配合工作

并行:多个处理器上多个任务

并发:一个处理器上多个任务

Parallel Scavenge收集器

多线程使用复制算法的新生代收集器,关注点与CMS等收集器尽可能缩短停顿时间不同,其目标是达到一个可控制的吞吐量(吞吐量=运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)),称为吞吐量优先收集器。

Serial Old收集器

Serial老年代版本,单线程收集器,使用“标记-整理算法”。

Parallel Old收集器

Parallel Scavenge的老年代版本,使用多线程和“标记-整理”算法。
Parallel Scavenge + Parallel Old真正的吞吐量优先收集器。

CMS收集器

基于“标记-清除”算法,过程分为四步:

  • 初始标记
  • 并发标记
  • 重新标记
  • 并发清除

其中初始标记和重新标记需要STW

缺点有三:

  1. 对CPU资源敏感,并发标记时用户线程没有暂停,收集器占用部分CPU资源,可能会使用户程序反应变慢
  2. 无法处理浮动垃圾,由于GC时用户线程还在进行,不停地会有新的垃圾产生,只能在下一次GC时处理,这部分垃圾叫做浮动垃圾
  3. 基于“标记-清除”算法,会产生大量空间碎片,导致无法找到足够大的连续空间分配而提前GC
G1收集器

运作步骤:

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收

特点:

  1. 并行与并发
  2. 分代收集(仍然保留了分代的概念)
  3. 空间整合(整体上属于“标记-整理”算法,不会导致空间碎片)
  4. 可预测的停顿(比CMS更先进的地方在于能让使用者明确指定时间片段内,消耗在垃圾收集上的时间)

内存分配策略

对象优先在Eden(年轻代)分配

新生代GC(Mirror GC):Java对象大部分都具备朝生夕灭的特性,Mirror GC非常频繁

老年代GC(Full GC):出现Full GC常伴随着Mirror GC,比Mirror GC慢十倍以上

大对象直接进入老年代

超过参数的对象直接在老年代分配

长期存活的对象将进入老年代

虚拟机给每个对象定义一个对象年龄计数器,当对象在Eden出生并且熬过第一次GC进入Survivor空间,那么它的年龄即设为1,每熬过一次GC年龄就加1,达到阈值就会晋升到老年代中

对象年龄判断

然而也并不是一定要到达阈值才能晋升,如果在Survivor空间相同年龄的对象的总和大于Survivor空间的一半,大于等于该年龄的对象即可直接进入老年代

空间分配担保

Mirror GC之前虚拟机会检查老年代可用空间是否大于新生代所有对象大小总和,如果是,那么可以确保Mirror GC安全。如果不是的话,看是否允许担保失败(允许冒险),如果允许那么将检查老年代可用空间是否大于历次晋升对象大小的平均值,如果是的话将进行一次Mirror GC,尽管有风险会失败;如果小于那么将进行Full GC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值