jvm诊断与优化(4)

前面有说到堆的可用内存少于预期值。这与GC的算法有关,被其贪掉了。

GC主要是对堆的内存进行管理,用到的算法有

1.标记算法

   实现分为两个阶段,一:标记阶段; 二:清除阶段。通过根标记所有可达对象;在清除阶段时清除没有标记的对象。

这就堆区分活动对象与非活动对象的方式。

2.复制算法

   将内存空间分为两块,每次只使用其中一块,在垃圾回收时将存活对象复制到未使用的内存中,之后清除正在使用的内存(所有的对象)。这时这两块内存的角色就互换了,而后交替重复。这就是为什么新生代分为eden,s0,s1.而且s0与s1一样。并且系统会保留一个用来角色互换。s0和s1也称为survivor空间

3.标记压缩法

   在标记算法基础上添加了对内存的整理,因为如果单纯的删除会产生很多的零碎。所以对内存进行了整理,使其可以连续。在老年代中用到

4.分代算法

    将内存区间根据对象分成几块(堆中分成新生代与老年代)。根据每块内存区间的特点使用不同的回收算法

5.分区算法

   将整个堆空间划分成连续的不同小区间。每个小区间都独立使用。这种算法是可以控制一次回收多少的空间。因为如果堆空间越大,那么GC一次所要的时间就越长,从而产生停顿也就越长。分区会减少GC所产生的停顿

最后的归总

新生代中: 在eden先标记活动对象 -> 将活动对象复制到s0/s1中,清空eden -> 标记s0/s1的活动对象 ->复制到老年代中,清除s0/s1。

 所有将创建的实例都在新生代中。新生代回收的频率是很高的,但每次回收耗时都很短。

老年代中:标记活动对象 -> 清除非活动对象 -> 整理老年代中的空间

 在经过多次GC后还存活下来的实例把它放到老年代中,老年代回收次数少,且耗时长。


你可能感兴趣的:(jvm诊断与优化(4))