Java技术,IBM风格: 垃圾收集策略,第1部分: 不同的策略提供了灵活性2011-01-30 IBM Mattias Persson可以使用 4 种不同的策略配置 IBM Developer Kit for the Java 5.0 Platform(IBM SDK)中的垃圾收集(GC)。本文(关于 GC 的两篇文章的第一篇)介绍不同的垃圾收集策略并讨论它们的性质。在阅读本文之前,您应该对 Java 平台中的垃圾收集有基本的认识。第 2 部分将给出一种选择策略的量化方法,以及一些示例。为什么要有不同的 GC 策略?能够使用不同的策略使开发人员增加了对应用程序的控制能力。有许多种 GC 算法,每种算法各有优缺点,这取决于工作负载的类型。(如果您不熟悉 GC 算法的一般性主题,那么请参见 参考资料 中其他读物的链接。在 IBM SDK 5.0 中,可以用 4 种策略 之一配置垃圾收集,每种策略都使用自己的算法。默认策略对于大多数应用程序已经足够了。如果对应用程序的性能没有特别的要求,那么您对本文(和下一篇文章)的内容可能不感兴趣;可以在不改变 GC 策略的情况下运行 IBM SDK 5.0。但是,如果应用程序需要最优的性能,或者很关注 GC 停顿时间的长度,那么请读下去。您会看到最新的版本比以前的版本提供了更多选择。那么,为什么不让 Java 运行时的 IBM 实现自动地替您做出选择呢?因为这不总是可行的。运行时很难了解您的需要。在某些情况下,希望应用程序有很高的吞吐量;而在其他情况下,希望减少停顿时间。表 1 列出可用的策略并解释每种策略应该在何时使用。后面几节分别详细描述每种策略的性质。
| 策略 | 选项 | 描述 |
| 针对吞吐量进行优化 | -Xgcpolicy:optthruput (可选) | 默认策略。对于吞吐量比短暂的 GC 停顿更重要的应用程序,通常使用这种策略。每当进行垃圾收集时,应用程序都会停顿。 |
| 针对停顿时间进行优化 | -Xgcpolicy:optavgpause | 通过并发地执行一部分垃圾收集,在高吞吐量和短 GC 停顿之间进行折中。应用程序停顿的时间更短。 |
| 分代并发 | -Xgcpolicy:gencon | 以不同方式处理短期存活的对象和长期存活的对象。采用这种策略时,具有许多短期存活对象的应用程序会表现出更短的停顿时间,同时仍然产生很好的吞吐量。 |
| 子池 | -Xgcpolicy:subpool | 采用与默认策略相似的算法,但是采用一种比较适合多处理器计算机的分配策略。建议对于有 16 个或更多处理器的 SMP 计算机使用这种策略。这种策略只能在 IBM pSeries® 和 zSeries® 平台上使用。需要扩展到大型计算机上的应用程序可以从这种策略中受益。 |
一些术语的定义吞吐量是应用程序处理的数据量。衡量吞吐量的标准是与具体应用程序相关的。停顿时间是垃圾收集器将所有应用程序线程停下来,从而对堆进行收集所经历的时间。在本文中,用表 1 中命令行选项中的缩写来表示这些策略:optthruput 表示针对吞吐量进行优化,optavgpause 表示针对停顿时间进行优化,gencon 表示分代并发,subpool 表示子池。何时应该考虑采用非默认的 GC 策略?建议您总是先使用默认 GC 策略。在放弃默认策略之前,需要了解在哪些情况下应该采用其他策略。表 2 给出了一些原因:
| 切换到 | 原因 |
| optavgpause | 我的应用程序无法忍受那么长的 GC 停顿时间。如果 GC 停顿时间能够减少的话,性能降低一些也可以接受。 我的应用程序正在一个 64 位平台上运行并使用非常大的堆 —— 超过 3 或 4GB。我的应用程序是一个 GUI 应用程序,我很关注用户响应时间。 |
| gencon | 我的应用程序分配了许多短期存活的对象。 堆空间出现碎片化。我的应用程序是基于事务的(也就是说,在事务提交之后,事务中的对象就不再存活了)。 |
| subpool | 在大型多处理器计算机上,我遇到了可伸缩性问题。 |