Java内存管理之基础概念——Hotspot的分代回收(Generational Collection)
这是Java内存管理系列文章的第二篇,上一篇是Java内存管理之基础概念——GC(Garbage Collection)的基本概念。
如果大家读过本系列的第一篇文章Java内存管理之基础概念——GC(Garbage Collection)的基本概念就会理解到实现一个优秀的GC算法的确是一个很大的挑战。Hostspot虚拟机采用了“分代回收”的策略,而“分”的非常重要的一个依据就是根据对象存在的时间的长短分成若干个“代(Gerneration)”,每个代上可以采取不同的GC策略。而采用这种“分代回收”策略是利用了2条潜规则,而且这两条潜规则不只限于Java
- 绝大对数的对象不会被长时间引用,这些对象在他的“青年期”就会被回收。
- 几乎不存在很老和很新对象之间的引用
依据这两条潜规则,Hotspot分离出新生代(Yound Generation)和旧生代(Old Generation)。由于新生代的空间通常都比较小而且可能存在大量不再被引用的对象,所以针对新生代的GC执行频率高、速度快。
在新生代中存在了一定时间还没被GC掉的对象最终会被提升到旧生代。旧生代空间比新生代的要大,但它的占用率增长会比较缓慢,因此,旧生代的GC执行频率低,但需要更长的时间来完成。
对新生代的GC侧重的是速度而且执行频繁,与此相反旧生代的GC侧重的是空间的利用率,即便在旧生代GC频率低的情况下依然要能够正常地工作。
另外还有一个永生代,永生代中的保存的对象都是JVM用来方便管理GC的,例如类和方法对象以及它们的描述对象。
新生代由一个Eden区域和2个survivor空间构成。绝大多数对象先分配到Eden中(有一些大的对象会可能会直接分配到旧生代中),survivor空间中的对象至少经历过一次新生代的GC,所以这些对象在被转移到旧生代之前都先暂且保留在survivor空间中。同一时间两个survivor空间中有一个用来保存对象,而另一个是空的,用来在下次的新生代GC中保存对象。
