java平台通过垃圾回收机制来进行内存的自动管理。但是具体垃圾回收的机制是什么样的呢。
垃圾回收器要进行的三大任务:分配内存、保证被引用的对象不被回收、保证不再被引用的对象被回收。
回收过程
基本策略:分代回收。
内存区域分为三个世代,年轻代、年老代、持久代。划分世代的一个理由基于对象存活时间的统计规律。例如一个应用大部分的对象存货的时间都非常短,例如局部对象存货的时间就是方法执行的过程中。这些对象都存储在年轻代中,基于这种存活时间非常短的特点,可以开发有针对性的算法。年老代存储存活时间比较长的对象。持久代主要保存java的类信息,对垃圾回收影响不大。但是如果有一些动态载入或者执行的类的场景,例如hibernate等。则可能需要设置一个比较大的持久空间来来存储这些动态增加的类。设置持久代空间的参数是-XX:MaxPermSize=<N>。
年轻代回收算法:年轻代又分为伊甸园和两个以上存活区,伊甸园是进行内存分配的地方,是一个连续空闲的内存块,以便快速的进行内存分配。存活区有一个保持空白。内存回收的时候(一般是),伊甸园和非空的存活区中还存活的对象根据存活时间拷贝到另一个存活区或者年老代。原来的存活区清空,变成新的非空存活区。伊甸园清空,又变成了连续空闲的内存块。一个对象在年轻代中经历了N次垃圾回收后仍然存活,就会被复制到年老代中而不是复制到空白存活区中。年轻代区域比较小,大部分对象不再存活,所以查找存活对象效率较高。回收过程如下图所示
年老代和永久代回收算法:对于年老代和永久代采用了标记-清除-压缩的机制。标记过程找出还存活的对象,清除是进行内存区域遍历,并清除掉非存活对象的内存区域,压缩则是进行内存碎片整理,使存活对象的内存分布在一端的连续区域,方便进行内存的复制和清除。
回收机制:串行回收和并行回收。串行回收常用在单CPU环境中,回收过程中,程序将停止应用响应,专心进行垃圾回收操作。并行回收常用在多CPU的服务器环境中,可以在应用运行的同时进行标记存货对象进行垃圾回收。
添加参数-verbose:gc参数可以查看垃圾回收运行结果
回收时机
GC有两种类型:Scavenge GC和Full GC。他们触发的时机不同
Scavenge GC触发时机:年轻代的的伊甸园区满或者年轻代中某个非空存活区满。将会频繁触发,速度快,效率高。
Full GC触发时机:Full GC对所有的内存区域进行整理,比较慢。在以下情况被触发
1.年老代被写满
2.持久代被写满
3.调用System.gc()