垃圾回收机制

堆内存的分配与回收

由于目前收集器都采用分代算法,因此Java堆可以分为新生代和老年代。
堆
分代回收原理:对象首先被分配在新生代,经历过垃圾回收后若仍存活,则移到老年代。但这样老年代很快会被填满,导致触发Major GC,性能受影响。
于是将新生代分为Eden区和Survivor区,Eden满时触发Minor GC,将存活的对线移至Survivor区。这样直到对象经历过一定次数的回收仍存活时,才将其移到老年代,这样就减少了Major GC(可视为Full GC)。

那为什么要设置俩Survivor区?答案是为了解决内存碎片问题。
单一Survivor区:
单Survivor
双Survivor区(保证有一个Survivor区为空,实现连续存储):
双Survivor
对于需要大量连续内存空间对象(如数组),为避免频繁复制导致效率降低,直接将其分配到老年代。

判断对象是否可回收

引用计数法

给对象添加一个引用计数器,为0时则可回收。
简单、高效,但难以解决对象间循环引用的问题,因此不被使用。

可达性分析法

以GC Roots对象为起点,向下搜索引用链。若一个对象与GC Roots没有任何引用路径,则判定为可回收。

可作为GC Roots的对象

  • 虚拟机栈(栈帧中的局部变量表)中引用的对象
  • 本地方法栈中引用的对象
  • 方法区中静态属性引用的对象
  • 方法区中常量引用的对象
  • 所有被同步锁持有的对象

死缓

对象被判断为不可达后,会被第一次标记,同时进行筛选:
①对象重写了finalize方法 ②对象的finalize方法未被虚拟机调用过
当满足任一条件,则执行finalize方法并放入队列进行二次标记,这之后才会被真正回收。

引用的种类

强引用

最普遍的引用。
内存不足时,JVM也不会回收强引用对象,只会抛出OutOfMemoryError。

软引用

内存够用时,JVM不会回收;内存不足时,JVM回收软引用对象。

弱引用

垃圾回收器一旦发现只有弱引用的对象,就会进行回收。
不过垃圾回收线程的优先级很低,不一定很快能发现这些对象。

虚引用

主要用来跟踪对象被垃圾回收的活动,必须和引用队列联合使用。

后两个很少使用,一般通过弱引用来加速垃圾回收速度,避免内存溢出。

垃圾收集算法

标记-清除算法

标记不能回收的对象,然后同一回收掉所有没标记的对象。
缺点:①效率不高 ②内存碎片问题

标记-复制算法

将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。这样就使每次的内存回收都是对内存区间的一半进行回收。
标记-复制

标记-整理算法

标记后,不是直接回收未标记对象,而是将标记对象向一端移动,然后清理掉边界外的内存。
标记-整理

综合应用

新生代中,每次收集都有大量对象被回收,于是选用“标记-复制”算法,复制少量存活对象即可完成回收。
老年代中,对象存活率较高,且没有额外空间进行分配担保,于是使用“标记-整理”算法进行回收。

垃圾收集器

Serial收集器

单线程进行收集,并且必须暂停其他所有工作线程。
新生代采用标记-复制算法,老年代采用标记-整理算法。

ParNew收集器

Serial收集器的多线程版本。

Parallel Scavenge收集器

JDK1.7&1.8 默认收集器,以实现最大CPU吞吐量为目标。

CMS 收集器(Concurrent Mark Sweep)

使用标记-清除算法,以获取最短用户线程停顿时间为目标。
回收步骤
1.初始标记:暂停用户线程,记录直接与GC Root相连的对象,速度很快。
2.并发标记:同时开启GC和用户线程,跟踪标记可达对象(不完整,因为用户线程会实时更新)。
3.重新标记:暂停用户线程,修正并发标记期间因用户线程而变动的可达对象的标记。
4.并发清除:同时开启GC和用户线程,清理掉判断死亡的对象。
缺点
· 因为标记和清除都是并发进行,不适合CPU核数低的服务器。
· 因GC和用户线程并行产生的浮动垃圾,无法在本次垃圾收集进行清除。
· 标记-清除算法产生的内存碎片问题

G1 收集器

JDK1.9 默认收集器
抛弃分代概念,将内存空间划分为多个区域(Region),维护一个优先级列表。垃圾回收时,根据系统允许的最长收集时间,优先回收垃圾最多的区域。
优点是可以精确地控制停顿时间,在不牺牲吞吐量的前提下实现短停顿垃圾回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值