在jvm5.0上垃圾回收调优(1)

来源:互联网 发布:鲁大师 硬件体检 优化 编辑:程序博客网 时间:2024/04/30 09:59
      

这篇文章是oracle官方的一篇文章,比较长,翻译的不是很好,有兴趣可以看看原文。地址:http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#1.1.Introduction%7Coutline

1.介绍

Java2平台的标准版本(J2SE TM platform)被应用于从桌面的小applet到在大型服务器上的web服务的多种应用程序。在J2SE平台的1.4.2版本有四种垃圾收集器可供选择,但是如果用户不知道该选择哪一个,那么串行垃圾收集器(serialgarbage collector)常常会被使用。在5.0版本垃圾收集器是依据应用启动所在机器的类别进行选择。(原文:Inversion 5.0 the choice of the collector is based on the class of themachine on which the application is started)

垃圾收集器的“智能选择”通常情况下会更好,但不总是最好的。对于那些希望对垃圾收集器做出自己选择的用户,这篇文档将会提供如何进行选择的知识。它首先会讲述垃圾收集器的通常特性以及调优选项,以便更好地利用这些特性。关于串口垃圾收集器的例子将在下文中被给出。然后就选择其他垃圾收集器应当被考虑的因素讨论其他垃圾收集器的具体特点。

什么时候选择垃圾收集器和用户有关系?对许多应用来说,都没有关系。因为应用程序可以它的规范下运行,允许垃圾收集器出现适度频率的暂停和持续。一个大的应用程序需要平衡好大数量的线程,处理器、套接字、和大量的内存的例子并不属于这种情况(当使用串口收集器时)(原文:Anexample where this is not the case (when the serial collector isused) would be a large application that scales well to large numberof threads, processors, sockets, and a large amount of memory.)

Amdahl 观察到大多数的工作量并不能被完美地并行处理,其中一部分是顺序执行的,并不能从并行处理中受益。对J2SE平台来说确实是这样。需要详细说明的是对于JAVA平台的虚拟机来说,直到并且包括1.3.1版本都没有并行垃圾收集器。所以垃圾收集器在多处理器系统上的影响力相对于其他并行应用程序有所增长。

下面的图是一个完全可伸缩的,除了垃圾回收之外的理想系统的模型。红色的线是应用在单处理器系统上只花费了1%的时间用于垃圾回收。这就意味着在32个处理器的系统上失去了超过20%的吞吐量。当扩展到32个处理器时,如果在垃圾收集上花费10%的时间(不考虑在单处理器应用上进行垃圾回收的总计时间),那么超过75%的吞吐量丢失了。

这显示了在开发小系统时微不足道的速度问题在扩展到大系统时可能会成为系统主要的瓶颈。然而在减少这样的瓶颈时一些小小的改进可以使性能得到很大的提高。对于一个足够大的系统来说,选择一个正确的垃圾收集器并调优是非常值得的。

串口垃圾收集器对大多说应用来说都是合适的。每个其他的垃圾收集器都有一些新增的开销或复杂性,这是拥有特殊行为的代价。如果一个应用不需要这个替换收集器的特殊行为,那么就是用串口垃圾收集器。有一个串口垃圾收集器不是最好选择的情形的例子,即一个拥有重量级线程,运行在硬件上,需要大量的内存和处理器的大型应用程序。对于这种应用程序,我们可以选择吞吐量收集器thethroughput collector);

这篇文章是使用 J2SE平台的1.5版本和 Solaris TM 操作系统(SPARC (R) PlatformEdition)作为基本的平台。因为它提供最具扩展性的硬件和来自J3SE平台的软件。然而,这篇文章也适用于其他受支持的平台,包括 Linux,Microsoft Windows, theSolaris Operating System (x86 PlatformEdition)。在某种程度上,在跨平台的硬件上都是可用的。尽管命令行选项在各个平台上都是一样的,但是一些平台可能默认有和这里描述不同的地方。

  1. 人体工程学

J2SE平台1.5版的新特色在这里称为人体工程学。它的目标是在最少命令行调优的情况下使JVM发挥良好的性能。人体工程学尝试去匹配以下最佳选择:

  • 垃圾收集器

  • 堆大小

  • 运行期编译

对于一个应用,这个选择假设应用运行所在机器的类别是应用特征的一个暗示(例如大型应用运行在大型机器上)。除了选择一种简化的调优垃圾收集方式,还可以使用吞吐量垃圾收集器,使用它用户可以对一个应用的最大暂停时间和希望吞吐量指定目标。这是与为了获得更好性能而指定堆大小做的一个对比。想要特别提高大型应用程序的性能,就需要巨大的堆空间。这篇文档中描述一般人体工程学的标题是”1.5JVM上的人体工程学”。建议在使用更详细的控制前,先详细了解在文档稍后提到它。

本文档中包括吞吐量收集器的人体工程学特性,提供了新的自适应大小政策的一部分。这包括新的选项去指定垃圾收集器性能的目标和额外的选项来优化性能。

J2SE平台的一个优势是使开发者免受内存分配和垃圾回收带来的复杂性。然而,一旦垃圾回收成为主要的瓶颈,就非常需要去了解它隐藏实现的某些方面。垃圾收集器假设应用使用对象的方式,可以通过调优参数的方式体现出来,然后通过调整参数就可以在不牺牲抽象的情况下提高性能。

在运行的程序中,当一个对象不再被任何引用时会被认为是垃圾。最直接的垃圾收集算法是简单地迭代每一个可以访问的对象,剩下的任何对象都被认为是垃圾。这种方法花费的时间和存活的对象的数量成正比,所以在大型应用程序中是禁止维护大量存活的数据。

J2SE平台的1.2版本开始,虚拟机结合代收集器generationalcollection)合并了许多不同的垃圾收集算法。当原生的垃圾收集器检查堆内每个活着的对象时,代收集器generationalcollection)利用一些观察大多数应用程序的属性得到的经验避免额外的工作。

这些观察到的属性中最重要的是早期死亡率infantmortality)。在下图(译者注:图没找到)中的蓝色区域是对象生命周期的一个经典分布。X轴是以分配的字节数为刻度表示的对象生命周期。Y轴表示的字节数量是和生命周期对应的对象的总字节数量。左侧的最高峰表示对象在被分配之后可以被立即回收 (例如,have "died") 。迭代这些对象,例如,在一个循环期间,这些对象常常是存活的。

一些对象可以存活地更久,所以分布可以延伸到右边。例如,通常有一些对象在初始化的时候被分配,可以一直存活到进程退出。在两个极值之间是那些用于在中间计算的对象,看这里块右边的早期死亡率infantmortality)最高。一些应用程序拥有不同非常不同的分布,但令人惊讶的是大量拥有这一般形状。对于大多数的对象早期死亡( "dieyoung")的事实,即,高效的垃圾收集器成为可能。


原创粉丝点击