堆分代(年轻代,老年代)

新生代内存分区

1,为什么需要把堆分代?

分代的唯一理由就是优化GC性能

  • 如果没有分代,所有的对象都在一块,GC的时要找到哪些对象是没用的,这样就会对堆的所有区域进行扫描。而我们的很多对象都是朝生夕死的。
  • 如果分代的话,把新创建的对象放到某一地方,当GC的时先把这块存“朝生夕死”对象的区域进行回收,这样就会腾出很大的空间出来。

2,Minor GC、Major GC和Full GC之间的区别

  • 从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC
  • Major GC 是清理老年代。
  • Full GC 是清理整个堆空间—包括年轻代和老年代。

3,年轻代中的GC

3,1,HotSpot JVM把年轻代分为了三部分:

1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1

3,2,年轻和老年代的关系

 

一般情况下,新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,
如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,
当它的年龄增加到一定程度时,就会被移动到年老代中。

3,3,年轻代采用复制算法回收对象

因为年轻代中的对象基本都是朝生夕死的(80%以上),所以在年轻代的垃圾回收算法使用的是复制算法,

将内存分为两块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面。
复制算法不会产生内存碎片。

3,4,年轻代回收的步骤:

1,在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。
2,紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,
3,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。
   年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。
4,经过这次GC后,Eden区和From区已经被清空。
   这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。
   不管怎样,都会保证名为To的Survivor区域是空的。
5,Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。

4.有关年轻代的JVM参数

1)-XX:NewSize和-XX:MaxNewSize

用于设置年轻代的大小,建议设为整个堆大小的1/3或者1/4,两个值设为一样大。

2)-XX:SurvivorRatio

用于设置Eden和其中一个Survivor的比值,这个值也比较重要。

3)-XX:+PrintTenuringDistribution

这个参数用于显示每次Minor GC时Survivor区中各个年龄段的对象的大小。

4).-XX:InitialTenuringThreshol和-XX:MaxTenuringThreshold

用于设置晋升到老年代的对象年龄的最小值和最大值,每个对象在坚持过一次Minor GC之后,年龄就加1。

 

posted @ 2018-03-07 17:54  假程序猿  阅读(4286)  评论(0编辑  收藏  举报