JVM垃圾回收

文中内容均出自: https://mp.weixin.qq.com/s/dMMf6XCshTqYtuqRPIL0vQ

 

JVM的内存区域如何识别垃圾?

1、引用计数法 

2、可达性算法

如何对垃圾进行回收?

1、标记清除算法

2、复制法

3、标记整理法

4、分代收集算法

 

Jvm垃圾回收
 
Java 比c /c++ 好的地方就是引入了垃圾自动回收机制
 
大部分时间是不用关心垃圾回收的,但在性能调优或者问题排查的时候需要关注full gc问题
 
对象实例和数组在堆上分配的,GC也只对这两类数据进行分析,这块也是我们之后重点要分析的对象
 
Java8 之后只有堆存在 gc 或者oom 问题
 
问题2:
如何识别堆中的数据是不是垃圾?
No1、引用计数法,一个对象被引用一次,就会增加一个次数,如果未被引用,则计数为0 ,对象可回收
问题:如果发生相互引用,则计数都为1,无法回收
 
No2、gc root 可达性算法,以gc root为起点出发,引出下一个节点,直到所有的节点都遍历结束,哪个对象不在任何一个引用链中,则会判断为垃圾
进行回收
 
哪些是gc root的对象?
虚拟机栈中引用的对象 ; 方法区中类静态属性引用的对象; 方法区中常量引用的对象; 本地方法中JNI引用的对象
垃圾回收等方法:
 
标记清除算法: 
会产生内存碎片
复制算法:
把堆分为两个区域,一个用来分配对象,一个不分配。 把区域1的存活对象标记出来,全部复制到区域2,然后对区域1进行全部清理。
解决了内存碎片的问题,但对于内存的使用率低
标记整理法:
就是在标记清除法之后再进行一次内存对象的移动
 
分代收集算法:
对象存活的周期不同,分为新生代和老生代,默认比例为1:2
 
新生代分为eden区 、 from survivor 区(s0)、 to survivor区(s1) 8:1:1 
新生代的gc叫做 Young GC (minor gc).  老生代的gc叫做 Old GC (Full GC)
 
新对象都会存放在eden区, 当eden区满了之后进行minor gc , 存活的对象放入到from survivor (s0)区,当再次进行minor gc的时候,会将eden和s0中存活的
对象都存入到s1区,
 
对象合适晋升到老年代 ?
1、 存在一个年龄阈值 比如是15 , 当发生minor gc时,s0中有个对象年龄达到15,则晋升到老年代 
2、大对象 当某个对象需要分配大量的利连续内存时,可以直接分配到老年代的内存中
3、当s0或者s1中相同年龄的对象大小加起来 > 空间的一半,则大于等于该年龄的对象会晋级到老年代
 
空间分配担保:
1、如果老年代的最大可用连续空间 > 新生代所有对象的空间,则进行minor gc 
2、如果小于,判断handlepromotionfailure ,如果允许: 老年代最大可用连续空间 > 历次晋升老年代的对象平均大小,则进行minor gc ,否则进行full gc 
 
Full gc 会stop the world , 就是只有垃圾回收的线程在工作,其他线程都不工作 
这时候服务器会拒绝服务
 
啥时候进行full gc ?  在safe point 
特定位置:
循环的末尾
方法返回前
调用方法的call之后
老生代的gc一般采用的是标记整理情理法  

posted on 2020-02-15 18:43  yingchen  阅读(284)  评论(0编辑  收藏  举报

导航