上一次我们已经介绍了Java内存模型,今天来简单介绍一下Java的垃圾回收机制。
Java 的自动内存管理主要是针对对象内存的回收和对象内存的分配。同时,Java 自动内存管理最核心的功能是 堆 内存中对象的分配与回收。
Java 堆是垃圾收集器管理的主要区域,因此也被称作 GC 堆(Garbage Collected Heap) 。
对象优先在eden区分配
目前主流的垃圾收集器都会采用分代回收算法,因此需要将堆内存分为 新生代 和 老年代 ,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。
大多数情况下,对象在新生代中eden区分配。当eden区没有足够空间进行分配时,虚拟机将发起一次 Minor GC .
我们先来看看 Minor GC 和 Full GC 有什么不同呢?
大对象直接进入老年代
大对象就是需要大量连续内存空间的对象(比如:字符串、数组)。
为什么要这样呢?
这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存复制。
长期存活的对象将进入老年代
既然虚拟机采用了分代收集的思想来管理内存,那么内存回收时就必须能识别哪些对象应放在新生代,哪些对象应放在老年代中。为了做到这一点,虚拟机给每个对象一个对象年龄(Age)计数器。
如果对象在 Eden 出生并经过第一次 Minor GC 后仍然能够存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为 1.对象在 Survivor 中每熬过一次 MinorGC,年龄就增加 1岁,当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold
来设置。