Java垃圾回收机制(笔记)

核心:GC是在什么时候,对什么东西,做了什么事情

1、垃圾回收的方法

1.1 引用计数法

原理:引用记数法就是判断对象的引用次数,给对象定义计算器,每增加一个实例,计数器就增加1。如果  计数器为0,就表示该对象没有被引用,可以回收

缺点:不能解决对象循环引用的问题。如果存在A和B两个对象,如果A引用B,B引用A,垃圾回收机制无法识别,也就不能完成垃圾回收。

例如:

鉴于引用计数法的缺点,JVM采用了可达性分析法

1.2 可达性分析法

原理:通过判断对象的引用链是否可达来决定对象是否可以被回收。可达性分析算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,通过一系列的名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连(就是从 GC Roots 到这个对象不可达)时,则证明此对象是不可用的。

如下图所示:

2、JVM在什么时候进行回收(什么时候)

(1)cpu空闲的时候

(2)在堆栈满了的时候

(3)主动调用 System.gc() 后尝试进行回收

3、对什么进行回收(对什么东西)

通过gc root搜索不到,并且经过第一次标记、清除后仍然没有复活的对象

4、如何回收(做了什么事情)

垃圾回收算法一共有四种,分别为:标记-清楚算法、复制算法、标记-整理算法、分代收集算法

每种算法并没有绝对的优劣,只是在不同的场景下适用的算法不同

3.1 标记-清除算法

> 原理:分为两个步骤,第一步是标记需要进行清除的对象;第二步是对被标记对对象进行回收;

> 优点: 简单

> 缺点:效率低,标记清除后会产生大量不连续的内存空间,导致程序在运行过程中如果需要分配较大的内存时,就会出现内存不足的情况,造成内存空间的浪费

如图所示:


3.2 复制算法

> 原理:将内存按照容量分为大小相同的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活的对象复制到另一块上,然后再把已经使用过的内存空间一次性清理掉。

> 优点:内存分配时不会出现内存碎片化的问题

> 缺点:实际使用内存缩小为原来的一半

如图所示:


3.3 标记-整理算法

标记-整理算法与标记-清除算法很像,区别在于:标记-清除算法只会对标记对象进行处理,而标记-整理算法不仅会对标记对象进行处理,还会对未标记对象进行处理,从而避免了内存碎片的问题。

> 在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法。只需要付出少量存活对象的复制成本就可以完成收集。

> 老年代中因为对象存活率高、没有额外空间对他进行分配担保,就必须用标记-清除或者标记-整理。

如图所示:


3.4 分代收集算法

分代收集算法是一种比较智能的算法,也是JVM使用最多的一种算法,他本身并是不一种新算法,而是在具体的场景中自动选择以上三种算法进行垃圾回收。场景指的是JVM的哪个区域,1.7之前JVM把内存分为三个区域:新生代(Younger Generation),老年代(Old Generation)和永久代(Permanent Generation)


[注]:本文参考自网络,仅作个人学习笔记用途

你可能感兴趣的:(Java垃圾回收机制(笔记))