Java知识点复习——JVM GC分代收集回收算法

Java虚拟机相关知识点主要包括,Java虚拟机的内存结构垃圾回收算法。但是其中扩展的内容还蛮多的,比如什么时候出现OutofMemory(OOM),对象实例存放的在哪里,垃圾处理器工作过程,都有哪些垃圾回收算法,哪些对象会被回收,什么时候进行GC操作等一些问题,所以我在复习的过程中,按照下图的顺序思考问题和学习。所以本文也知识一个学习思路,并不是全面的讲解每一个算法以及知识点。

Java知识点复习——JVM GC分代收集回收算法_第1张图片

首先问自己的第一个问题就是Java虚拟机的内存结构是什么?
很多很多资料上都有说一共分为五个部分:
线程共有的:方法区,堆
线程私有的:Java 栈,本地方法栈,程序计数器
(想深入了解的可以另行查一下资料)
但是我在学习的过程中,发现易混的就是堆,非堆和栈这三个部分。
程序计数器:是单独的较小的内存空间,每个线程都有独立的程序计数器,随着线程的创建而创建,结束而死亡。
栈:为虚拟机执行Java方法服务,会跟随线程的创建而创建,结束而死亡。
方法区:NO-Heap(非堆)存放已经加载的类信息,常量,静态变量等。
而我们在最需要关注的就是堆区,因为这里又被称为GC堆,几乎所有的对象实例和数组都在这里分配内存。

知道了Java虚拟机的内存结构之后,就有第二问题,垃圾回收的时候回收哪些对象?
首先通过第一个问题我们已经明确了垃圾回收主要产生在堆中,那么垃圾处理器如何判断回收哪些对象呢?
主要有两个算法进行判断:引用计数法(基本已经不再使用),可达性分析算法。
简单的理解引用计数法,就是记录使用次数。
而可达性分析算法,从GC root作为起点去搜索可达的存活的对象。

知道如何确定哪些对象需要回收以后,我们的第三个问题就是如何回收对象?(这个问题也有人会问又哪些垃圾回收器?其实我看了好多遍这部分知识,但是我发现我完全记不住这些垃圾回收器的名字,也许是因为我都没有实际用过。但是我记住了垃圾回收算法,所有垃圾处理器都是垃圾回收算法的组合。)
主要有三种垃圾回收算法:
1.标记-清除
顾名思义,就是把标记过对象的留下来,剩下的就删除掉,不过会有内存碎片。
2.标记-复制
也是记住名字,我们就可以知道,我们需要两块相同大小的空间,把第一部分有用的对象复制到第二部分,这样不会有内存碎片,但是会需要更多的内存空间。
3.标记-整理
和第一个算法优点相似,标记的对象留下来,但不是进行删除,而是把标记过的对象向一侧移动,也就是边标记边整理。
垃圾回收器:
新生代:都是标记复制算法Serial,Parallel Scavenge 和 Parallel New。Serial 是单线程的,后两个是多线程,但是吞吐量不同。
老年代:Serial Old 和 Parallel Old,以及 CMS。前两个是标记整理算法,一个单线程,一个多线程。CMS是标记清除算法。
取代CMS的Garbage First垃圾回收器,横跨新生代和老年代,是标记整理算法,多线程。
这样是不是比直接的看垃圾处理器更容易记住。

在分类垃圾处理器的时候,我们提到了新生代和老年代,难么这里我们就来学习一下什么是分代回收算法?
(上面图片有画出 整个Java堆空间的内存分配情况)
其实就是我们把Java堆整个空间按照“年代”Generation的方式划分开。
新生代:Young Generation 又分成三个部分,Eden,Survivor1,Survivor2。所有对象开始都在eden区,在执行Minor GC时,利用标记-复制算法把不用的对象复制到Survivior1,此时Survivor2为空(一直保持有一个为空的情况),然后在标记的过程中,继续不用就把Survivor1的放在Survivor2里面,每次都标记➕1,达到设置次数(默认15)以后数据利用标记-复制算法写到老年代中。
老年代:Old Generation,在这个区域会有会有Major GC和Full GC

第五个问题,就是扩展到什么时候会执行Full GC?
1.老年代写满。
2.持久代写满 持久代在1.8以后变成元数据区
3.垃圾回收策略改变。
4.System.GC()被调用。

暂时通过JVM的问题扩展到这五个问题,之后更深入的问题会再进行更新

你可能感兴趣的:(Java知识点复习,jvm)