JVM内存结构之堆的垃圾回收过程

前言:

        上一篇文章介绍了简单的JVM内存结构,然后本篇重点解释堆区域的垃圾回收清理过程(jdk1.8),为什么说堆呢?因为垃圾回收的核心就是堆区域来做的,像栈区域执行完就会把线程释放掉。方法区(元空间)基本很少会被GC回收,而且一般存储常量、静态变量这种生命周期较长的数据,元空间的回收条件也非常苛刻。

堆的垃圾回收结构:

JVM内存结构之堆的垃圾回收过程_第1张图片

什么是垃圾:

        个人理解,如果一个对象自己没有引用,也没有被别人引用,那这个对象存在与不存在都跟程序运行没有关系,那就是垃圾对象。 

堆的划分为两部分:

        年轻代、老年代。

年轻代:

        年轻代默认占堆中1/3的区域,并且年轻代划分为三块区域,1块Eden区域,两块survivor区域,默认比例为8:1:1划分。

老年代:

        老年代默认占堆中2/3的区域。

minor gc:

        专门负责年轻代的gc过程,因为默认new出的对象都放在堆中,其实就是放在Eden区域。由执行引擎控制执行。


full gc:

        发生在老年代的gc,发生full gc会对整个堆空间进行垃圾收集,由执行引擎控制执行。

gc roots:

        简单理解就是可以被引用或者引用别人的一些变量、对象等等都可以作为gc roots。

STW:

        暂停所有当前线程,让gc查找垃圾对象,如果不做STW,那么会造成对象的引用状态一直变化,gc效率太低,并且不能准确扫描对象。

描述堆中垃圾回收过程:(jdk1.8默认垃圾回收器是parallel)

        堆中存放我们new出来的对象,存放的区域就是Eden区域,但这个区域存满以后就会做minor gc,首先进行STW,然后通过gc roots去查找这些对象是不是有引用关系,通过关系来判断是否是垃圾,如果能够找到引用就不是垃圾,找不到就是垃圾(也叫可达性分析算法),minor gc过程中我们有一部分是垃圾一部分不是垃圾,会将这些垃圾对象清除,然后非垃圾对象会放到第一块survivor区域s0中,并且将对象的分代年龄+1,分代年龄(用来区分对象生命周期的一种标识,比如parallel默认对象分代年龄达到15岁就放到老年代中)。此时一次minor gc结束。第二次minor gc的时候会将Eden区域和s0、s1区域一块扫描(因为第一次的时候s区域是空的),扫描后会有对象进入surviver区域中s0并且分代年龄+1,上一次在s0的对象会放到s1中并且分代年龄+1。进入surviver区域中的对象会在s0到s1之间来回存放如果一直没有被清除,那么等到分代年龄达到15岁的时候放入老年代中。我们可以推断出,老年代做full gc的频率应该远远小于年轻代minor gc,老年代等到存放对象快满的时候会做full gc,扫描老年代中的对象是否是垃圾,如果都不是并且此时还有对象要进入老年代,那此时就会报OOM(内存溢出错误)。

 在jdk1.8中,垃圾回收器是paraller,在minor gc 和 full gc过程时都会做STW,直到垃圾回收结束.

        后续会更新多种垃圾收集器Serial、Parallel、Parnew、CMS、G1,会介绍这些垃圾收集器的特点,以及收集运行过程。

        不足之处还望多多指教!!!

你可能感兴趣的:(性能调优jvm,mysql,tomcat,java)