JVM 运行时内存划分
跳到导航
跳到搜索
根据对象的生命周期的长短把对象分成不同的种类(年轻代、老年代和永久代),并分别进行内存回收,这就是分代垃圾回收。
分代垃圾回收算法
分代垃圾回收算法的主要思路如下所示:
把堆分成两个或者多个子堆,每一个子堆被视为一代。
在运行的过程中,优先收集那些年幼的对象,如果一个对象经过多次收集仍然存活,那么就可以把这个对象转移到高一级的堆里,减少对其的扫描次数。
目前最常用的 JVM 是 SUN 公司(现被 Oracle 公司收购)的 HotSpot,它采用的算法为分代回收。
HotSpot 分代回收
HotSpot 把 JVM 中堆空间划分为三个代:年轻代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation)。
- 年轻代(Young Generation):被分成3个部分,一个 Eden 区和两个相同的 Survivor 区。Eden 区主要用来存储新建的对象,Survivor 区也被称为 from 和 to 区,Survivor 区是大小相等的两块区域,在使用“复制”回收算法时,作为双缓存,起到内存整理作用,因此,Survivor 区始终都保持一个是空的
- 老年代(Old Generation):主要存储生命周期较长的对象,超大的对象(无法在年轻代分配的对象)
- 永久代(Permanent Generation):存放代码、字符串常量池、静态变量等可以持久化的数据。SunJDK 把方法区实现在了永久代。
年轻代和老年代的垃圾回收方法
因为永久代基本不参与垃圾回收,所以,这里重点介绍的是年轻代和老年代的垃圾回收方法。
新建对象优先在 Eden 区分配内存,如果 Eden 区已满,那么在创建对象的时候,会因为无法申请到空间而触发 minorGC 操作.
minorGC 主要用来对年轻代垃圾进行回收:
把 Eden 区中不能被回收的对象放入到空的 Survivor 区,另一个 Survivor 区里不能被垃圾回收器回收的对象也会被放入到这个 Survivor 区,这样能保证有一个 Survivor 区是空的。如果在这个过程中发现 Survivor 区也满了,那么就会把这些对象复制到老年代(Old Generation),或者 Survivor 并没有满,但是有些对象已经存在了非常长的时间,这些对象也将被放到老年代中,如果当老年代也被放满了,那么就会出发 fullGC