注:新生代和老年代都是Java堆中的内存空间,划分方法跟存储对象的生命周期有关。永久代是方法区中的。
一:新生代
新生代是堆中的一块内存空间,大约占据堆内存的1/3,用来存放新创建的对象,对象生命周期较短。在新生代中进行内存回收时采用的是复制算法(参考GC篇),具体如下:
1。新生代中的内存分为三个区:Eden区、SurvivorFrom区、SurvivorTo区,三个区的内存大小比为8:1:1。当新生代进行一次内存回收时,Eden区和SurvivorFrom区的存活对象会被保存到SurvivorTo区,然后Eden区和SurvivorFrom区的内存就会被清空。最后SurvivorFrom区和SurvivorTo区会互换身份,保存有存活对象的SurvivorTo区变成SurvivorFrom区,被清空的SurvivorFrom区变成SurvivorTo区。由于创建对象进行内存分配时只使用了Eden区和SurvivorFrom区,所以堆内存的利用率为90%。
二:老年代
每当新生代对象熬过一次内存回收时,这些对象的年龄就会加1,当对象年龄达到默认值15时,这些对象就会被移到老年代。另外如果新生代一次内存回收时存活的对象数目大于SurvivorTo区的存放空间,也就是说SurvivorTo无法将一次内存回收存活对象全部存储,那么这些存活对象会直接被放到老年代。或者当创建对象时对象占用内存比较大,也会直接将该对象放入老年代。
在老年代中由于对象生命周期都比较长,所以采用的内存回收方法是标记-整理算法(参考GC篇)。每当老年代内存不够时就会进行内存回收。
三:永久代
永久代指的是方法区,由于方法区的内容生命周期都很长,进行一次内存回收效果不明显,所以一般可以不进行内存回收,当然当方法区内存不够时还是要进行内存回收的,回收的具体内容参考GC篇。