Java垃圾回收(GC)机制总结
概述
本文汇总了垃圾回收(GC)相关知识,精炼了部分理解复杂的部分,可能会忽略某些特殊情况,是对GC的总体整理分析。
哪些区域需要回收?
java内存可大体分为:方法区,堆(heap),虚拟机区,本地方法栈,程序计数器(PC),这五块。虚拟机区,本地方法栈,程序计数器(PC)与具体线程绑定,生命周期和线程相同,某个线程回收时,与此线程绑定三块区域内存同时回收。而方法区,堆(heap)是由所有线程共用。同时也是java程序内存使用的大部分,存放着类和对象。
java的GC针对的是:方法区和堆区域的内存回收。
如何知道哪些对象需要回收?
1.引用计数法:给对象添加一个引用计数器,当增加一个引用时+1,引用失效时-1.为0则清除。
注意:出现形似于下图的引用关系(循环引用)时,当棕色的引用消失时,从逻辑上不再对小圆引用,但是所有的小圆的引用计数仍都为1,所以都不会清除。这种情形引用计数法就捉襟见肘。
2. 可达性法分析:首先认为Root开始搜索,如果没有搜索到则认为不可达,则该对象逻辑上不再被使用,需要清除。Root的数目并不止一个,需要一个 GC Root Set 去保证 仍需要使用的对象不会被清除。
可被选为GC Roots Set的对象有以下四种
1.栈帧中的本地表量表(应是局部表量表)中的引用对象。(我认为,此处《深入理解JVM》叫法有误)
2.方法区中的类静态属性引用的对象。
3.方法去中常量引用的对象。
4.本地方法栈中JNI引用的对象。
3.四种引用分析:https://blog.****.net/qq_36144187/article/details/81564747
类的回收:
需要同时满足下列三个条件,才有可能被回收,仅仅是有可能。
1.该类的所有实例都已经被回收。
2.加载该类的ClassLoader被回收
3.对应的java.lang.Class 对象没有在任何地方被引用。
基础垃圾收集算法
1.标记--清除算法
分为两个阶段,标记出需要回收的对象,然后回收。
缺点:会产生大量的碎片,容易触发更多次的GC。
2.标记--整理算法
分为两个阶段,标记存活的对象,然后把存活移动到一段,回收所有边界之外的内存。
缺点:单次的GC时间更长,
3.复制算法
将内存划为大小完全一样的两块内存,只是用其中的一块,每次gc就将所有存货对象,移到另一块,清除本块内存。
缺点:会浪费50%的内存
垃圾收集基本思想
1.分代思想:把堆分为新生代,老年代,s0,s1这四块。不同的区域使用不同的算法。一般对象分配在新生代,当新生代满触发 Minor GC。若对象可以s区域,则移入s区域,这个区域采用复制算法,多次仍存在,则移入老年代,老年代满触发 Major GC。或者大对象直接在老年代分配。Full GC 则是对整个堆进行GC操作。
2.Stop-The-World:就是全局停顿,因为当内存在被使用时,总是会产生垃圾,若一边清理一边运行,那么垃圾总是清理不干净,更重要的是标记--整理算法将无法使用。
综合垃圾收集器
1.串行收集器(SerialGC):
1.最古老,最稳定
2.可能会产生较长时间的停顿
3. -XX:+UseSerialGC
- 新生代,老年代使用串行回收
- 新生代复制算法
- 老年代标记-压缩
2.ParNew:
1.新生代并行,老年代串行。
2.可以理解为Serial在新生代的并行版本
3. -XX:+UseSerialGC
- 多线程支持多核
- -XX:ParallelGCThreads 限制线程数量
- 基本和串行收集器一致
3.CMS收集器
1.停顿时间短,清理不能完全干净
2.采用标记-清除算法
3.不能在快满的使用
4. -XX:+UseConcurrentMarkSweepGC
- 并发阶段会降低吞吐量
- 针对老年代
- 新生代仍用ParNew
5.工作流程:
-初始标记:根可以直接关联到的对象
-并发标记:一边运行一边标记全部对象
-重新标记:产生 Stop The world ,修正并发标记
-并发清除:基于标记结果直接清理对象
4.G1收集器
1.取消新生代老年代的物理隔离,使用大小相同的Region分割堆。
2.停顿时间可以预测控制
3.整体上采用标记-整理,局部来看采用两个Region之间的复制算法
4. -XX:+UseConcurrentMarkSweepGC
- 优化了大于4G以上的超大堆
- 充分利用Cpu和多核环境,适合现代的算法
- 增加了与 Region关联的 Remembered Set 避免全堆扫描
5.工作流程:与CMS流程大致相同。
总结
内存回收和垃圾收集器虽然影响程序的并发性,吞吐率。但仍需一个良好的程序才能发挥调优的作用。同时没有固定的收集器、参数的组合,只能针对不同的程序调优。
本文引用:
《深入理解JVM》 周志明
炼数成精 JVM相关课程
http://blog.jobbole.com/109170/