引用:http://www.daniel-journey.com/
可能会对原文加上个别注释,用红色 标识出来
==================================================
这是Java内存管理系列文章 的 第一篇。
GC是一种自动内存管理程序,与之相对应的是C++采用的内存管理方式。GC主要的职责就是分配内存;保证被引用的对象始终在内存中;把不被应用的 对象从内存中释放。被引用的对象称之为Live 对象;不被引用的对象就是Dead对象,是需要回收的。(引出概念弱引用,weak reference )任何事物都有光面和黑暗两面,原因很简单GC是一个很复杂的东西:-)。
GC会自动计算对象被引用的情况,只要对象不在被引用,相应的内存就会被回收,而C++中需要开发人员通过代码来“显示”地回收内存,如果程序员没 有回收就会导致内存的泄露(内存泄露的原因有很多种这只是其中一个)。C++中还有经常出现的一个问题是一个对象在还有其他引用存在的情况下,就被程序给 回收了,导致其他引用访问该对象时出现严重错误。另外,GC非常重要的一点就避免内存碎片,道理跟windows的磁盘整理一样,把使用中各个内存块整合 起来,这样才能保证有足够的空间来存储大对象。
一个理想的GC要能够满足以下几点:
这是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频率低的情况下依然要能够正常地工作。
另外还有一个永生代 (Permanent Generation) ,永生代中的保存的对象都是JVM用来方便管理GC的,例如类和方法对象以及它们的描述对象。(Sun的JVM不回收PermGen,由于动态语言产生类会比较多,有时就会出现PermGen Overflow。另外推荐用JRockit JVM )
新生代由一个Eden区域和2个survivor空间构成 。绝大多数对象先分配到Eden中(有一些大的对象会可能会直接分配到旧生代 中),survivor空间中的对象至少经历过一次新生代的GC,所以这些对象在被转移到旧生代之前都先暂且保留在survivor空间中。同一时间两个 survivor空间中有一个用来保存对象,而另一个是空的,用来在下次的新生代GC中保存对象。