Java垃圾回收

垃圾收集机制是 Java 的招牌能力,现在写出来未免有些老生常谈了。

一、垃圾标记算法

引用计数算法

每个对象都有一个引用计数器,当对象在某处被引用时,它的计数器就加1,引用失效减1。当计数器变为0时,该对象不能被使用。

缺点是没有办法解决对象的循环引用。

可达性分析(根搜索算法)

将对象及其引用关系看作一个图,选定一些活动的对象作为GC Roots,并组成根对象集合,然后以这些GC Roots的对象为起始点,向下搜索,如果目标对象到GC Roots是连接着的,我们则称该目标对象是可达的,如果目标对象不可达,则说明目标对象是可以被回收的对象。J

VM 会把虚拟机栈中引用的对象、本地方法栈JNI引用的对象、方法区中运行时常量池引用的对象、方法区中静态属性引用的对象、运行中的线程等作为 GC Roots。

二、垃圾收集算法

标记 - 清除算法

标记出可以回收的对象,再回收被标记的对象所占用的空间。

标记-清楚算法是基础,后面算法都是在此基础上改进的。

标记-清楚效率并不高,并且容易产生大连不连续的内存碎片。

复制算法

将存活的对象复制到新的区域,拷贝过程中将对象顺序放置。

避免内存碎片化。复制算法被广泛应用于新生代中。

标记 - 压缩算法(标记 - 整理)

类似于标记 - 清除,但为避免内存碎片化,在标记可回收的对象后将所有存活的对象压缩到内存的一端。以确保移动后的对象占用连续的内存空间。

三、分代收集算法

Java堆区基于分代的概念,分为新生代、老年代。

新生代再细分为Eden空间、Form Survivor空间和To Survivor空间。

四、垃圾收集过程

Java 应用不断创建对象,通常都是分配在 Eden 区域,当其空间占用达到一定阈值时,触发Minor GC。仍然被引用的对象存活下来,被复制到 JVM 选择的 Survivor 区域,而没有被引用的对象则被回收。存活下来的对象标记存活时间。

Eden再次达到Minor GC触发条件,另外一个 Survivor 区域则会成为 to 区域,Eden 区域的存活对象和 From 区域对象,都会被复制到 to 区域,并且存活的年龄计数会被加 1。

直到有对象年龄计数达到阈值,这时候就会发生所谓的晋升(Promotion)过程,过阈值的对象会被晋升到老年代。

注意:新生代存活的对象都放在了to空间,GC时,to和from互换位置,每次都要保证to是空的,这就是复制算法在新生代的应用。老年代则会采用标记-压缩或者标记-清楚算法/

五、Java中GC

Serial GC:串行运行;作用于新生代;复制算法;响应速度优先;适用于单CPU环境下的client模式。

ParNew GC:并行运行;作用于新生代;复制算法;响应速度优先;多CPU环境Server模式下与CMS配合使用。

Parallel Scavenge GC:并行运行;作用于新生代;复制算法;吞吐量优先;适用于后台运算而不需要太多交互的场景。

Serial Old GC:串行运行;作用于老年代;标记-整理算法;响应速度优先;单CPU环境下的Client模式。

Parallel Old GC:并行运行;作用于老年代;标记-整理算法;吞吐量优先;适用于后台运算而不需要太多交互的场景。

CMS GC:并发运行;作用于老年代;标记-清除算法;响应速度优先;适用于互联网或B/S业务。

G1 GC:并发运行;可作用于新生代或老年代;标记-整理算法+复制算法;响应速度优先;面向服务端应用。

 

发布了21 篇原创文章 · 获赞 0 · 访问量 326
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览