什么是分代垃圾回收策略? java
根据对象的生命周期的长短把对象分红不一样的种类(年轻代,年老代和持久代)并分别进行内存回收,就是分代垃圾回收!值得注意的是,这种划分对象的手段并非自动进行的,而是伴随着回收过滤进行的,也就是说年轻代与年老代之间的转换是伴随着对象回收的,只有通过了回收的洗礼后一些对象才会被选中成为年老代,而另一些不幸的对象则早早地就被系统取走了小命。 算法
为何要运用分代垃圾回收策略?在java程序运行的过程当中,会产生大量的对象,因每一个对象所能承担的职责不一样所具备的功能不一样因此也有着不同的生命周期,有的对象生命周期较长,好比Http请求中的Session对象,线程,Socket链接等;有的对象生命周期较短,好比String对象,因为其不变类的特性,有的在使用一次后便可回收。试想,在不进行对象存活时间区分的状况下,每次垃圾回收都是对整个堆空间进行回收,那么消耗的时间相对会很长,并且对于存活时间较长的对象进行的扫描工做等都是徒劳。所以就须要引入分治的思想,所谓分治的思想就是因地制宜,将对象进行代的划分,把不一样生命周期的对象放在不一样的代上使用不一样的垃圾回收方式。 spa
如何划分?将对象按其生命周期的不一样划分红:年轻代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)。其中持久代主要存放的是类信息,因此与java对象的回收关系不大,与回收息息相关的是年轻代和年老代。 线程
年轻代:年轻代又进一步能够划分为一个伊甸园(Eden)和两个存活区(Survivor space),伊甸园是进行内存分配的地方,是一块连续的空闲内存区域,在里面进行内存分配速度很是快,由于不须要进行可用内存块的查找。新对象是老是在伊甸园中生成,只有经受住了必定的考验后才能后顺利地进入到存活区中,这种考验是什么在后面会讲到。把存活区划分为两块,其实也是为了知足垃圾回收的须要,由于在年轻代中经历了“回收大劫”未必就可以进入到年老代中。系统老是把对象放在伊甸园和一个存活区(任意的一个),在垃圾回收时,根据其存活时间被复制到另外一个存活区或者年老代中,则以前的存活区和伊甸园中剩下的都是须要被回收的对象,只要对这两个区域进行清除便可,两个存活区是交替使用,循环往复,在下一次垃圾回收时,以前被清除的存活区又用来放置存活下来的对象了。通常来讲,年轻代区域较小,并且大部分对象是须要进行清除的。 对象
年老代:在年轻代中经历了N次回收后仍然没有被清除的对象,就会被放到年老代中,能够说他们都是久经沙场而不亡的一代,都是生命周期较长的对象。对于年老代和永久代,就不能再采用像年轻代中那样搬移腾挪的回收算法,由于那些对于这些回收战场上的老兵来讲是小儿科,而是采用一种称为“标记-清除-压缩(Mark-Sweep-Compact)”的算法。标记的过程是找出当前还存活的对象,并进行标记;清除则是遍历整个年老区,找到已标记的对象并进行清除;而压缩则是把存活的对象移动到整个内存区的一端,使得另外一端是一块连续的空间,方便进行内存分配和复制。 生命周期
持久代:用于存放静态文件,好比java类、方法等。持久代对垃圾回收没有显著的影响。 内存
何时进行回收?因为对象进行了了分代处理,因此垃圾回收区域和时间也不同。回收(Gabage Colection )的类型有两种:Scavenge GC和Full GC。 io