Java堆是Java虚拟机管理的最大的一块内存空间,主要存放对象实例。
在Java中,堆被分为两块区域:新生代、老年代。
堆大小=新生代+老年代。(分别占堆空间为1/3、2/3)
新生代
新生代又被分为Eden、from survivor、to survivor(8:1:1)
新生代这样划分是为了更好的管理堆内存中的对象,方便GC算法-->“复制算法”来进行垃圾回收。
JVM每次只会使用Eden和其中一块survivor来为对象服务,所以无论什么时候,都会有一块survivor空间,因此新生代实际可用空间为90%。
新生代GC(minor gc):指发生在新生代的垃圾回收动作,因为Java对象大多数都是“朝生夕死”的特性,所以minor GC非常频繁,使用复制算法快速的回收。
新生代几乎是所有Java对象出生的地方,Java对象申请的内存和存放都是在这个地方。
当对象在Eden(包括一个survivor,假如是from),当此对象经过一次minor GC后仍然存活,并且能够被另一块survivor所容纳(这里的survivor则是to),则使用复制算法将这些仍然存活的对象复制到to survivor区域中,然后清理掉Eden和from survivor区域,并将这些存活的对象年龄+1,以后对象在survivor中每熬过一次则+1,当达到某个值(默认为15),这些对象会成为老年代!
事情不是绝对,有些较大的对象(需要分配连续的内存空间),则直接进入老年代。
老年代
老年代GC(major GC):指发生在老年代的垃圾回收动作,所采用的的是“标记--整理”算法。
老年代几乎都是从survivor中熬过来的,不会轻易“死掉”,因此major GC不会像minor GC那样频繁
什么叫复制算法
两块survivor,每次使用其中的块。当这一块使用完了,就将还存储着的对象复制到另一块survivor上面,然后再把已经使用过的内存空间一次清理掉,下图为示意图。
优点:不用考虑内存碎片问题,实现简单,运行效率高。
缺点:当对象存活较高(PS:老年代)时,就要进行较多的复制操作,效率会很低。
什么叫标记--整理算法
与“标记-清理”算法相似,只是后续不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存,下图为示意图。
“标记--整理”算法示意图
网友评论