其他分享
首页 > 其他分享> > 十二、垃圾回收篇

十二、垃圾回收篇

作者:互联网

一、概述

关于垃圾收集有主个经典问题:

1、什么是垃圾?

垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。

如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空间会一直保留到应用程序结束,被保留的空间无法被其他对象使用。甚至可能导致内存溢出。

2、为什么需要GC?

3、Java中垃圾回收的重点区域是?

垃圾回收器只作用在堆和方法区。其中,Java堆是垃圾收集器的工作重点。

从次数上讲:

 

二、垃圾回收算法

1、垃圾标记阶段算法

在堆里存放着几乎所有的java对象实例,在GC 执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶段。

(1)引用计数算法

引用计数算法(Reference Counting)比较简单,对每个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。

原理:

对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,即表示对象A不可能再被使用,可进行回收。

优点:

缺点:

Java并没有选择引用计数,是因为其存在一个基本的难题,也就是很难处理循环引用关系。

(2)可达性分析算法(或根搜索算法、追踪性垃圾收集)

相对于引用计数算法而言,可达性分析算法不仅同样具备实现简单和执行高效等特点,更重要的是该算法可以有效地解决在引用计数算法中循环引用的问题,防止内存泄漏的发生。

相较于引用计数算法,这里的可达性分析就是Java、C#选择的。这种类型的垃圾收集通常也叫作追踪性垃圾收集(Tracing Garbage collection)。

原理:

其原理简单来说,就是将对象及其引用关系看作一个图,选定活动的对象作为GC Roots,然后跟踪引用链条,如果一个对象和GC Roots之间不可达,也就是不存在引用链条,那么即可认为是可回收对象。

思路:

优点:

实现简单,执行高效 ,有效的解决循环引用的问题,防止内存泄漏。

GC Roots:

在Java 语言中, GC Roots 包括以下几类元素:

小技巧:由于Root 采用栈方式存放变量和指针,所以如果一个指针,它保存了堆内存里面的对象,但是自己又不存放在堆内存里面,那它就是一个Root 。

注意点:

如果要使用可达性分析算法来判断内存是否可回收,那么分析工作必须在一个能保障一致性的快照中进行。这点不满足的话分析结果的准确性就无法保证。

这点也是导致GC进行时必须“stop The world”的一个重要原因。即使是号称(几乎)不会发生停顿的CMS收集器中,枚举根节点时也是必须要停顿的。

 

2、垃圾清除阶段算法

(1)标记-清除算法

(2)复制算法

(3)标记-压缩算法

(4)分代收集算法

(5)人增量收集算法

(6)分区算法

 

 

三、相关概念

四、垃圾回收器

五、分析GC日志

标签:对象,内存,十二,回收,算法,GC,引用,垃圾
来源: https://www.cnblogs.com/shiblog/p/15956179.html