Java堆内存划分

新生代、老年代、永久代。

Eden Space大约占80%的空间。From Space与To Space占用20%的空间。如果Eden Space与From Space区域有可回收的对象,就将少量不能被回收的对象复制到To Space中,然后将Eden Space与From Space全部回收。

新生代:Java虚拟机在每次垃圾回收的时候都回去扫描所有存活的对象,默认情况下对这些对象执行一个加一操作,如果对象经过15次以上的GC扫描以后还是没有被系统回收的情况下,就认为该对象不属于新生代对象,就让该对象跨度到老年代。

老年代:在新生代中经历了N次垃圾回收后依然存活的对象,就会被放到老年代中。因此可以认为老年代中存放的是一些生命周期比较长的对象。

永久代:用于存放静态文件,如Java类信息、方法等。永久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的永久代空间来存放这些运行过程中新增的类,永久代大小通过-XX:Max设置。

MinorGC、FullGC:

Minor GC:主要用于新生代的垃圾回收算法,采用的是复制算法。新生代几乎是所有Java对象出生的地方,即Java对象内存申请以及存放都是在这个地方。Java中的大部分对象通常不需要长久存活,具有朝生夕灭的性质。当一个对象被判定为”死亡”时,GC就有责任来回收掉这部分内存空间。新生代是GC收集垃圾的频繁区域。

当对象在Eden(包括一个Survior区域,假设是From区域)出生后,在经过一次Minor GC后,如果对象还存活,并且能够被另一块Survivor区域所容纳(上面已经假设是From区域,所以这里就是指的To区域,即To区域有足够的内存空间来存储Eden与From区域中存活的对象),则使用复制算法将这些任然还存活的对象复制到另一块Survivor区域(这里指的是To区域)中,然后清理所使用过的Eden以及Survivor区域(这里指的是From区域),并且将这些存活对象的年龄设置为1,以后对象在Survivor区域每熬过一次Minor GC就将对象年龄+1,当对象年龄到达某一个值时(默认是15,可以通过参数-XX:MaxTenuringThreshold来设定),这些对象就会变成老年代。

但是对于一些比较大的对象(即需要分配一块比较大的连续内存空间)则是直接进入到老年代。

Full GC是发生在老年代的垃圾收集动作,采用标记-清除算法。比Minor GC慢很多,Minor GC触发的频率比较高。

在内存中的老年代对象几乎都是在Survivor区域熬过来的,它们是不会那么容易被”回收”的。因此Full GC发生的次数不会有Minor GC那么频繁,并且做一次Full GC要比进行一次Minor GC的时间更长。另外,标记-清除算法会产生许多的内存碎片(即不连续的内存空间),此后需要为较大的对象分配内存时,若无法找到足够的连续的内存空间,就会提前触发一次GC收集动作。

results matching ""

    No results matching ""