垃圾回收常见算法
1.引用计数法(Reference Counting)
比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个应用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。
2.复制(Copying)
此算法把内存空间划为两个相等区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中,此算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还可以进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍的内存空间。
绿色:已被使用,但还存活的内存空间。比如new了一个对象,这个对象引用了其它方法,或持有其它对象,它持有的对象正在执行某个方法。
蓝色:正在运行中的内存空间。比如某个对象在此时正在执行某个方法。
灰色:待回收的垃圾内存。
白色:未使用的内存空间
橙色:一大块空的内存区域。比如survivor区域的,from区域和to区域。
3.标记-清除法(Mark-Sweep)
最核心,最基础的内存回收算法,后面许多算法,都是基于这个算法之上延伸的。
此算法执行分两阶段。第一阶段从引用根节点(GC ROOTS)开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。
此算法需要暂停整个应用(stop the world),同时会产生内存碎片。
因为回收后的内存空间联系不紧密,存在碎片。
4.标记-整理(Mark-Compact)
此算法结合了“标记-清除“和“复制”两个算法的优点。也是分为两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把已标记对象和存活对象“压缩”到堆的一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。
5.可达性分析算法
详见我的另一篇文章《jvm虚拟机学习 可达性算法》
6.分代算法
垃圾收集算法
垃圾回收算法是垃圾回收器的方法论,垃圾收集器就是对垃圾回收方法的具体实现。
Scavenge GC (次收集)和 Full GC的区别(全收集)
新生代GC(scavenge GC):Scavenge GC是指发生在新生代的GC,因为新生代的JAVA对象大多都是朝生夕死,所以Scavenge GC非常频繁,一般回收速度也比较快。当Eden区域不足以为对象分配内存空间时,触发Scavenge GC,清除非存活对象,并且把存活对象,移动到Survivor区域,然后整理Survivor的两个区域。这种GC不针对老年代内存空间,需要使用速度快,效率高的算法。
老年代GC(full GC):full GC是指发生在老年代的GC,出现了full GC一般伴随着至少一次的Minor GC(老年代的对象大部分是Minor GC过程中从新生代进入老年代的),比如:分配担保失败。full GC的速度一般比minor GC慢10倍以上,当老年代内存不足,或显示调用System.gc()方法时,会触发Full GC。
分代垃圾回收器
新生代收集器
串行收集器(Serial)
serial收集器是hotspot运行在client模式下的默认新生代收集器,它的特点是只用一个CPU/一条收集线程去完成GC工作,且在垃圾收集时必须暂停其他工作线程(stop the world,后面简称stw),可以使用:XX+UseSerialGC打开。
虽然是单线程收集器,但是简单高效,在VM管理内存不大的情况下收集几十M,上百M的停顿时间完全可以控制在几十毫秒到一百多毫秒内。
并行收集器(parNew)
ParNew收集器是Serial收集器的多线程版本,除使用多线程进行GC收集外,包括Serial可用的所有控制参数,收集算法,STW,对象分配规则,回收策略等都与Serial完全一样,-XX:+UseConcMarkSweepGC。
来源:oschina
链接:https://my.oschina.net/xiaoyoung/blog/3159036