写点什么

JVM 垃圾回收原理简述

用户头像
Mars
关注
发布于: 2020 年 12 月 19 日

JVM堆空间划分

JVM堆空间分为:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation

年轻代分为:一个Eden区,2个相同的Survivor区。所有新对象都会在Eden区创建,如此划分主要是为了让生命周期短的对象尽量留在年轻代。当Eden区不足时,进行minor collection,把存活对象拷贝到survivor区。

垃圾回收具体流程

1.       对象在Eden区完成内存分配。

2.       如果Eden区已满,就会触发minor collection进行年轻代垃圾回收。

3.       当minor collection时,Eden区不能被回收的对象放入到其中一个空的survivor区,另一个survivor区不能被回收的对象也会被放入这个survivor区,始终保证一个survivor区是空的。

4.       上一步中,如果survivor区满了,这些则会被拷贝到老年代。或者survivor区未满,但是部分对象已经足够old,也会被放入old区(由参数-XX:MaxTenuringThreshold决定)。

5.       当Old区满后,无法将新生代中多次复制后依然存活的对象复制进去的时候,就会对老年代的内存空间进行一次full GC,所以根据应用程序对象存活时间,合理设置老年代和新生代空间比例,对JVM垃圾回收性能影响很大,JVM设置老年代和新生代比例参数:-XX:NewRatio

注意:JDK8:默认新生代:老年代比例值是1:2;新生代大小=1/3堆空间大小。JDK8的堆:新生代、老年代、元空间。

 

判断哪些对象需要被回收

通常使用如下两种方法:

1.       引用计数器:通过一个对象的引用计数器来判断对象是否被引用。每当对象被引用了,计数器就加1,当引用失效,计数器减1。如果计数器为0,则说明对象不被引用,可以被垃圾回收。注意:计数器虽然实现简单,判断高效,但存在对象之间互相循环引用的问题,所以JVM不适合引用计数方式。

2.       可达性分析:采用GC Roots作为起点进行搜索,能够达到的对象都是存活的,不可达的对象可被垃圾回收。

具体过程:从线程栈帧中的局部变量或者方法区的静态变量出发,将这些变量引用的对象进行标记,然后看这些被标记的对象是否引用了其他对象,继续进行标记,所有被标记的对象都是被使用中的对象,而没有被标记的对象就是可以回收的垃圾对象。

垃圾回收算法

JVM对垃圾对象占用的空间进行回收,回收的三种方法:

清理:将垃圾对象占用内存清理掉,其实JVM不会真的对这些垃圾内存进行清理,而是将这些垃圾对象占用的内存空间标记为空闲,记录在一个空闲列表里,当应用程序需要创建新对象的时候,就从空闲列表中找一段空闲内存分配个新对象。

压缩:从堆对象头部开始,将存活对象拷贝放在一段连续的内存空间,那么其余空间就是连续的空闲空间。

复制:将堆空间分成两部分,只在其中一部分创建对象,当这部分空间用完的时候,将标记过的可用对象复制到另一个空间中。





JVM垃圾回收器算法

l  串行回收器

l  并行回收器

l  并发回收器CMS

1.       初始化标记(stop the world)

2.       并发标记(标记与处理任务并行)

3.       重标记(stop the world)

4.       并发清理

l  G1回收器



发布于: 2020 年 12 月 19 日阅读数: 13
用户头像

Mars

关注

还未添加个人签名 2018.06.12 加入

还未添加个人简介

评论

发布
暂无评论
JVM 垃圾回收原理简述