庞玉栋个人博客、人生苦短-我用Python

深入解析Java垃圾回收机制

发布时间:8年前热度: 1216 ℃评论数:

引入垃圾回收 哪些内存需要回收? 引用计数法 可达性分析 如何回收 Marking 标记 Normal Deletion 清除 Deletion with Compacting 压缩 为什么需要分代收集? JVM的分代 新生代 老年代 永久代 分代垃圾收集过程详述 引入垃圾回收

JAVA

程序计数器、 虚拟机栈、 本地方法栈3个区域随线程而生,随线程而灭;栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。 每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的(尽管在运行期会由JIT编译器 进行一些优化,但在本章基于概念模型的讨论中,大体上可以认为是编译期可知的),因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。 而Java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间时才能知道会创建哪些对象,这部分内存的分配和回收都是动态的,垃圾收集器所关注的是这部分内存—–《深入理解Java虚拟机》 自动垃圾回收机制就是寻找Java堆中的对象,并对对象进行分类判别,寻找出正在使用的对象和已经不会使用的对象,然后把那些不会使用的对象从堆上清除。 自动垃圾回收机制就是要解决三个问题:

哪些内存需要回收? 什么时候回收? 如何回收? 哪些内存需要回收?

引用计数法

对于第一个问题,也就是判断是否还需要使用,最简单的方法就是通过目前是否有引用指向这个对象,如果没有就说明这个对象不会再被使用了,如果有就说明这个对象可能还会继续被使用,这种通过引用是否存在的方法就叫做引用计数法,但这个方法存在一个问题就是无法解决对象循环引用的问题,因此又出现了可达性分析的方法来判断对象是否可以被会回收。

可达性分析

这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。 在Java语言中,可作为GC Roots的对象包括下面几种:

虚拟机栈(栈帧中的本地变量表)中引用的对象。 方法区中类静态属性引用的对象。 方法区中常量引用的对象。 本地方法栈中JNI(即一般说的Native方法)引用的对象。 如何回收

垃圾收集器通常会帮我们在后台自动进行垃圾回收。关于具体的回收过程只要有以下这些步骤

Step 1: Marking 标记 第一步就是标记,也就是垃圾收集器会找出那些需要回收的对象所在的内存和不需要回收的对象所在的内存,并把它们标记出来,简单的说,也就是先找出垃圾在哪 所有堆中的对象都会被扫描一遍,以此来确定回收的对象,所以这通常会是一个相对比较耗时的过程

Step 2: Normal Deletion 垃圾收集器会清除掉上一步标记出来的那些需要回收的对象区域

手机扫码访问