垃圾回收(GC)机制
垃圾回收(GC)机制
- 1.为什么会存在GC?
- 2.图解堆内存
- Minor GC
- 3.1 针对什么?
- 3.2 什么时候触发?
- 3.3 做了什么?
- 3.4 具体过程
- 3.5 对于用可达性分析法搜索不到的对象,GC并不一定会回收该对象
- Full GC
- 4.1 什么时候触发?
- 4.2 针对什么?
- 5.Minor GC 担保机制
1.为什么会存在GC?
用过c++写程序的人应该都曾经被如何进行内存管理而折磨的头皮发麻,而java的垃圾回收机制则正是解决了内存管理的问题!!!这就使得java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。
2.图解堆内存
1.垃圾回收GC一般分两种:普通GC(Minor GC)、全局GC(Full GC or major GC)
注:JVM在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代
3. Minor GC
3.1 针对什么?
通过可达性分析法可以确定无法搜索到的对象和可以搜索到的对象。对于搜索不到的对象进行标记。笼统的说就是java对象,只针对新生代触发。
3.2 什么时候触发?
当Eden区满时,触发Minor GC。
3.3 做了什么?
- 对于可以搜索到的对象进行复制操作,对于搜索不到的对象,调用finalize()方法进行释放。
默认情况下,当某个对象经过了15次Minor GC则会把这个对象移动到老年代中
XX:MaxTenuringThreshold
这个值是用于设置对象在新生代中存活的次数
- 在Minor GC时,会把存活的对象复制到to space区域,如果to space区域不够,则利用担保机制进入老年代区域。
3.4 具体过程
当GC线程启动时,会通过可达性分析法把Eden区和From Space区的存活对象复制到To Space区,然后把Eden Space和From Space区的对象释放掉。当GC轮训扫描To Space区一定次数后,把依然存活的对象复制到老年代,然后释放To Space区的对象。
3.5 对于用可达性分析法搜索不到的对象,GC并不一定会回收该对象
要完全回收一个对象,至少需要经过两次标记的过程。
- 第一次标记:对于一个没有其他引用的对象,筛选该对象是否有必要执行finalize()方法,如果没有执行必要,则意味可直接回收。(筛选依据:是否复写或执行过finalize()方法;因为finalize方法只能被执行一次)。
- 第二次标记:如果被筛选判定位有必要执行,则会放入FQueue队列,并自动创建一个低优先级的finalize线程来执行释放操作。如果在一个对象释放前被其他对象引用,则该对象会被移除FQueue队列。
4. Full GC
4.1 什么时候触发?
- 调用System.gc时,系统建议执行Full GC,但是不必然执行
- 老年代空间不足
- 方法区空间不足
- 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
4.2 针对什么?
针对老年代的GC,偶尔伴随对新生代的GC以及对永久代的GC
5.Minor GC 担保机制
在发生minor gc之前,虚拟机会检测 : 老年代最大可用的连续空间>新生代all对象总空间
- 满足:minor gc是安全的,可以进行minor gc。
- 不满足:查看虚拟机HandlePromotionFailure参数
1.true,允许担保失败,会继续检测老年代最大可用的连续空间>历次晋升到老年代对象的平均大小。若大于,将尝试进行一次minor gc,若失败,则重新进行一次full gc。
2.false,则不允许冒险,要进行full gc(对老年代进行gc)
还没有评论,来说两句吧...