以下内容自sun白皮书1-150020中找到,由于加上我自己的理解,所以不是翻译文章(英语不给力,翻译不好).其中我只关注了回收的抽象机制,对于引用计数,具体算法等未涉及.
hotspot(j2se 5.0,按白皮书上的说法也适用于6.0)使用的是所谓的Generational Collection机制,也就是把对象分为young和old(还有一种是permanent,暂时不鸟他),young对象经过几次回收后(存活较长时间后),就会成为old对象.之所以采用这种机制,是基于以下观察:大部分新建对象的引用不会持续太久,也就说是会die
young;少部分的引用会持续下来.
因此,young generation
进行Collection会更多,因此使用的算法对时间效率的要求高.而old
generation 保存的数据较多,使用的算法对空间的要求效率相对而言要求就较高了.把对象分为不同的generation,便于采用不同的算法进行操作.
对应的,可以把HotSpotJVM的内存分为:young
generation ,oldgeneration ,permanent generation.在这里默认首先把对像都放到区域的左边.
J2SEHotSpot JVM
的 4中垃圾回收器都是属于generational collection.
一般说来,新建对象时一般都是在young里面分配内存,old里面储存的是young中经过几次回收依然存活的对象以及一些一开始就在old中分配的大对象.而permanent
generation里面保存的是类信息和元数据.
younggeneration分为一个Eden区域和两个survivor
区域.对象在Eden区域生成,经过一次GC后存活下来的对象进入survivor中,并在此经过更严格的考验,然后进入old
.同一时间只有一个survivor区域保存对象,另一个为空.
当young区域满了后,就会执行young区域的GC算法.当old和permanent区域满了后,会先执行young的GC.再执行old和permanent的GC,如果old区域对象过多无法执行young的GC,那么在young区域执行old的GC算法(因为内存空间耗费较少),但是CMS回收器的old算法不行,下面会说明原因.
对于多线程的应用.JVM
使用一个Thread-LocalAllocation Buffers ,为每个线程分配一个区域来分配对象,以排除线程竞争.如果此区域满了的话就使用锁.
HotSpot的四种GC
回收器:
串行化回收serial collector:
特点:回收时会暂停应用.
young区域:将Eden和某个Survivor区域中的存活的对象复制到另一个Survivor区域(设为TO)(大对象直接放到old区域).如果TO区域满了,则直接复制到old区域.
old区域:使用mark-sweep-compact GC算法,也就是先标记存活对象,然后清除废弃对象,然后把存活对象都移到一块区域,空出一片较大的空闲空间.
适用范围:大部分客户端的应用都可以使用这种回收算法,这也是HotSpot默认的回收算法.在现在的机器(06年)上一个64MB的区域的一次完全回收所需的时间不到半秒钟.
并行回收parallel collector:
特点:可以利用多核的CPU.
young区域:同样还是要暂停应用,基本机制和串行化差不多,不过是使用多线程.可以加快效率.
old区域:同串行化.
多核计算机上面可以使用.
并行压缩回收parallel compacting collector:
与并行回收相比,主要是在old区域有个新的算法,同时,按白皮书的说法,这种回收最终会替代并行回收.
young区域:同并行回收.
old区域:首先,把old分为几个连续的区域.然后,在每个区域并行的进行检查,标记出alive的对象(先标记出可以直接引用的对象,然后是所有的).然后开始对这些区域进行检查,得出密集程度(左边的区域肯定比右边的密集),从某个密集程度不很高的区域开始,并行的对右边区域进行压缩.
适应范围:对于多核,且对pause time有要求的环境下,使用并行压缩回收比并行回收要好.但是对于高共享率的服务器(也就说一台服务器运行多个应用),由于old区域的collection较慢,又是多线程,所以一个应用的GC会对其他应用造成影响.对应的解决方法:可以配置减少并行时的线程数目.
并行标记清除回收Concurrent Mark Sweep collector:
young区域:同并行回收.
old区域:分为几个步骤.
Initialmark:在需要执行GC时,先暂停应用,然后把所有直接引用到的对象进行标记.
Concurrentmark:然后继续应用,并同时对已标记对象进行检查,得到所有存活的对象.
remark:再次暂停应用,对Concurrent mark持续期间应用程序修改了的对象进行检查(新增的,废弃的),并标记存活对象.这个阶段持续时间较长,因此会使用多线程.在阶段结束后,所有的存活对象都被标记了,未标记的对象就是垃圾对象了.
sweep:停止暂停应用程序,然后把所有垃圾对象的空间释放.
与其他算法的不同点:
第一:不执行压缩.不过会通过计算将来可能的内存需求而合并/分割某些内存块.
第二:不是old区域要满了才执行GC,而是在空间小于一定程度时开始.
第三:由于没执行压缩,因此会产生碎片.
另外,CMS还可以使用增量运行方式,就是在Concurrentmark阶段只执行一部分工作,然后把资源还给应用程序.回收器的工作会分为几个部分并安排在两次young区域的回收空闲阶段完成.这种模式一般用在对暂停时间有要求,同时处理器数目不多的情况下(单核或双核).
总体说来,与并行回收相比,CMS降低了old GC的暂停时间(有时候效果很显著),轻微的加长了young
GC的时间(因为对象从young区域转到old区域时间会加长:没执行压缩,因此要先找到合适的区域),降低了整个系统的一些执行效率,以及很大的加强了对于内存空间的需求.
适用范围:对暂停时间有要求,服务器能够分配一些资源给GC线程.一般说来,适用于应用相对而言有一些比较大的old
generation,并且是多核处理器的服务器.比如说web server(这里特别指明web server了)
分享到:
相关推荐
文档接下来介绍J2SE 5.0 HotSpot JVM中的垃圾收集器,包括垃圾收集器的类型、快速分配、串行收集器、并行收集器、并行压缩收集器和并发标记-清除(CMS)收集器。此外,还探讨了自动选择收集器、堆大小和虚拟机的行为...
6. **Java 7与G1 GC**:2011年,Java 7引入了G1(Garbage First)垃圾回收器,它是一种并行、并发且具有低延迟特性的垃圾回收器,适用于大型应用。 7. **Java 8与元空间**:2014年,Java 8中,永久代被元空间...
- **HotSpot虚拟机**:J2SE 6.0中的HotSpot VM在垃圾回收、编译优化等方面都有显著提升,提高了整体运行效率。 - **内存管理**:内存分配和回收速度加快,减少了内存碎片,提高了系统性能。 4. **部署和安全** -...
7. J2SE 5.0 HotSpot JVM中的垃圾收集器: - Hotspot Generations:HotSpot JVM的堆通常分为新生代(Eden、Survivor)、老年代(Tenured Generation)。 - 垃圾收集类型:包括串行收集器、并行收集器、并行压缩...
《Java内存管理白皮书》深入探讨了Java虚拟机(JVM)中的内存管理机制,特别是Sun Microsystems在J2SE 5.0版本中的HotSpot JVM。本文将根据标题、描述、标签以及部分内容,详细解析Java内存管理的核心知识点,包括...
Java使用自动垃圾收集机制来回收不再使用的对象所占用的内存,以避免内存泄漏。垃圾收集器根据不同的策略和算法,如分代收集、标记-清除、复制、标记-整理等,来有效地管理和回收内存。 总的来说,JVM是Java生态...
本文档旨在对Sun J2SE 5.0版本中的Java HotSpot虚拟机(JVM)内存管理机制进行全面概述,包括不同类型的内存收集器及其配置方法、如何调整收集器内存区域的大小等。此外,还将提供一些影响内存收集器行为的常见选项,...
### JVM基础知识详解 #### HotSpot简介 HotSpot作为Oracle(原属SUN)的主要Java虚拟机实现,...HotSpot JVM提供了多种不同的垃圾回收器选项,可以根据应用的具体需求选择合适的垃圾回收策略,以达到最优的性能表现。
自最初的版本以来,JVM经历了多次重大改进,包括性能优化、垃圾回收机制的完善以及对多线程处理的支持。 1996年,Java 1.0发布,引入了JVM的第一个版本。这个版本的JVM执行效率相对较低,但为后来的优化打下了基础...
- **简单性**:具有类似于C++的语法结构,但去除了复杂的指针操作,并内置垃圾回收机制简化内存管理。 - **分布性**:Java设计之初就考虑到了网络环境下的应用,支持网络透明性。 - **安全性**:不支持指针操作,...