JVM运行时内存
Java堆从GC的角度可以细分为:新生代( Eden 区 、 From Survivor 区 和 To Survivor 区)和老年代
新生代
- 用来存放新生的对象,占据堆的1/3空间。
- 由于频繁创建对象,会频繁触发MinorGC进行垃圾回收
Eden 区
- java新生对象的出生地
- 如果创建的对象占用的内存很大,直接分配到老年代
- 当Eden区内存不够的时候就会触发MinorGC,对新生代进行一次垃圾回收
ServivorFrom
- 上一次GC的幸存者,作为这次GC的被扫描者
ServivorTo
- 保留了一次MinorGC中的幸存者
MinorGC的过程(复制->清空->互换)
- eden 、 servicorFrom 复制到 ServicorTo,对象年龄+1(若对象的年龄到达老年区的标准或者ServicorTo的内存不够位置,则直接赋值到来年代)
- 清空 eden 、 servicorFrom
- ServicorTo 和 ServicorFrom 互换
老年代
- 主要存放生命周期长的内存对象
- MajorGC 不会频繁执行,若执行MajorGC(标记清除算法) ,则一般在执行前会先执行MinorGC(复制清除)
- 老年代装不下的时候,就会出现OOM
永久代
- 内存的永久保存区域,主要存放Class和Meta(元数据)
- GC不会在主程序运行期间堆永久区域进行清理,所以会出现随着加载class的增多而胀满,最后出现OOM异常
- java8中永久代被元数据区所取代,元数据区并不在虚拟机中,而是是用本地内存。默认情况下,元空间的大小仅受本地内存限制。类的元数据放入 native memory, 字符串池和类的静态变量放入 java 堆中