垃圾回收机制

Posted zwz-bk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了垃圾回收机制相关的知识,希望对你有一定的参考价值。

一、如何确定对象是一个垃圾:
1.引用计数法:
每产生一个对象为其产生一个计数器,每当对象被引用计数器自增,当引用失效(赋予新值或引用超出作用范围时)自减。
当计数器值为0时,对象被认为是一个垃圾。此方法好处是短时间运行,不会长时间中断程序运行,缺点是无法处理循环引
用,会让其他引用这个对象的引用为null,还有就是比较消耗计算机的处理性能。
2.追踪法:
采用追踪法的垃圾回收器会从根节点遍历引用关系图,在遍历中遇到的对象就被标记为“活动”。遍历完成后,没有被标记
的就认为是垃圾。
二、常见的可回收对象
1.被赋值为null的
2.局部变量(for循环)
3.被弱引用与其关联的对象
三、典型的垃圾回收算法:
1.标记-清除算法:
此算法分为2个阶段,第一个阶段先从引用关系图出发,遍历中遇到的对象就标记。第二个阶段直接清除未标记的对象。
算法会暂停程序运行,产生碎片影响大对象无空间。
2.复制算法:
此算法将内存分为相同大小的2块,平时运行一块,当进行垃圾回收时,把正在使用的对象复制到另一边,这边进行垃圾回收。
好处是不会产生碎片问题而且是把正在使用的对象复制复制成本小,缺点是内存代价大。
3.标记-整理算法:
此算法分为2个阶段,第一个阶段先从引用关系图出发,遍历中遇到的对象就标记。第二个阶段把未标记的对象整理到堆的一
块。此算法避免了碎片问题,同时也避免了内存问题。
4.分代搜集算法
基于对对象生命周期分析得出的垃圾回收算法。分代搜集算法分为三代。
1.新生代:
一般来说新生成的对象放在新生代,新生代的目的就是处理生存周期短的对象。新生代又分为Eden区和两个Survivor区。
对象一般先放进Eden,如果Eden满了之后,把其中存活的对象复制到Survivor1中,如果Survivor1满了,把Survivor1中存
活的对象存到Survivor2中,如果Survivor2满了,把Survivor1区复制过来的并且此时还存活的对象复制到老年代。新生代
采用复制算法。
2.老年代:
一般新生成的大对象放在老年代,还有就是在年老代经过gc回收N次还存活的对象。老年代采用标记-整理算法。
3.永久代:
永久代一般储存的是类,常量,方法描述等静态文件。
扩展
GC的两种方式
Scavenge GC
一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且
把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代
。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用
速度快、效率高的算法,使Eden去能尽快空闲出来。
Full GC
对整个堆进行整理,包括Young、Tenured和Perm。
1.年老代(Tenured)被写满
2.持久代(Perm)被写满
3.System.gc()被显示调用

参考:https://blog.csdn.net/lufeng20/article/details/7402386














































以上是关于垃圾回收机制的主要内容,如果未能解决你的问题,请参考以下文章

垃圾回收机制与内存管理

JAVA垃圾回收机制的工作原理?

CMS垃圾回收机制

Python的垃圾回收机制原理

java垃圾回收机制

谈谈垃圾回收机制方式内存管理?