垃圾收集器
从台式机上的小程序到大型服务器上的Web服务,各种各样的应用程序都使用Java平台标准版(Java SE)。为了支持各种部署范围,Java HotSpot虚拟机实现(Java HotSpot VM)提供了多个垃圾收集器,每个设计满足不同的要求。这是满足大型和小型应用程序需求的重要部分。Java SE根据运行应用程序的计算机的类别选择最合适的垃圾收集器。但是,此选择可能并非对每个应用程序都是最佳的。具有严格性能目标或其他要求的用户,开发人员和管理员可能需要明确选择垃圾回收器并调整某些参数以实现所需的性能水平。本文档提供了有助于完成这些任务的信息。首先,在串行收集器的上下文中描述了垃圾收集器的一般功能和基本调整选项。然后介绍其他收集器的特定功能以及选择收集器时要考虑的因素。
垃圾收集器(GC)是一种内存管理工具。它通过以下操作实现自动内存管理:
-
将对象分配给年轻一代,并将老化的对象提升为老一代。
-
通过并发(并行)标记阶段查找旧一代中的活动对象。当Java堆总占用量超过默认阈值时,Java HotSpot VM会触发标记阶段。请参阅并发标记扫描(CMS)收集器和垃圾优先的垃圾收集器部分。
-
通过并行复制压缩活动对象来恢复可用内存。请参阅“并行收集器和垃圾优先的垃圾收集器”部分
什么时候选择垃圾收集器很重要?对于某些应用,答案永远是不可能的。也就是说,在存在垃圾收集的情况下,应用程序可以在频率和持续时间适度的暂停下表现良好。但是,对于大类应用程序却不是这种情况,特别是那些具有大量数据(数千兆字节),许多线程和高事务处理率的应用程序
阿姆达尔定律(给定问题中的并行加速受问题的顺序部分限制)意味着大多数工作负载无法完美并行化;某些部分始终是顺序的,不能从并行性中受益。Java平台也是如此。特别是,Java SE 1.4之前的Oracle针对Java平台的虚拟机不支持并行垃圾收集,因此,垃圾收集对多处理器系统的影响相对于其他并行应用程序而言会增加。
图1-1“比较垃圾收集中所用时间的百分比”中的图形对理想系统进行了建模,该系统除了垃圾收集(GC)之外,还具有完美的可伸缩性。红线表示应用程序仅在单处理器系统上花费1%的时间进行垃圾回收。在具有32个处理器的系统上,这意味着吞吐量损失超过20%。洋红色线表明,对于一个应用程序,其垃圾回收的时间为10%(在单处理器应用程序中,垃圾回收的时间不算多),扩展到32个处理器时,将损失超过75%的吞吐量。
图1-1比较垃圾回收中花费的时间百分比
这表明,在小型系统上进行开发时,可以忽略的速度问题可能会在扩展到大型系统时成为主要瓶颈。但是,在减少这种瓶颈方面进行小的改进可以提高性能。对于足够大的系统,有必要选择正确的垃圾收集器并在必要时进行调整。
串行收集器通常适合大多数“小型”应用程序(那些需要高达大约100兆字节(在现代处理器上为MB)的堆)。其他收集器具有额外的开销或复杂性,这是专门行为的代价。如果应用程序不需要备用收集器的特殊行为,请使用串行收集器。预计串行收集器不是最佳选择的一种情况是大型,高线程应用程序,该应用程序在具有大量内存和两个或多个处理器的计算机上运行。在此类服务器级计算机上运行应用程序时,默认情况下会选择并行收集器。
本文档是使用Solaris操作系统(SPARC Platform Edition)上的Java SE 8作为参考而开发的。但是,此处介绍的概念和建议适用于所有受支持的平台,包括Linux,Microsoft Windows,Solaris操作系统(x64平台版本)和OSX。此外,尽管某些选项的默认值在每个平台上可能有所不同,但提到的命令行选项在所有受支持的平台上均可用。
原文
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/introduction.html