在负载下jvm更快?

时间:2012-12-03 09:38:36

标签: performance jvm

许多个人经验,轶事证据和一些初步分析表明,Java服务器(运行,通常是Oracle的1.6 JVM)在负载量不足的情况下响应时间更快(显然只有一点)

我认为这不是纯粹的热点,因为当流量消失时,响应时间会再次减慢。

在许多情况下,我们可以通过平均服务器日志的响应时间来证明这一点......在某些情况下,平均速度高达20%,标准偏差更小。

任何人都可以解释为什么会这样吗?这可能是真正的影响,还是平均值只是误导?我已经看了很多年了,通过几个工作,并倾向于说它是一个事实,但没有解释为什么。

谢谢, 埃里克

1 个答案:

答案 0 :(得分:1)

编辑一个相当大的措辞编辑,并在整个过程中添加更多细节。

一些想法:

  1. 当一段代码执行得比其他部分(它是程序的热点)时,Hotspot开始了。这使得那段代码从那一点开始显着加快(对于正常路径)。热点编译后的调用率并不重要,所以我认为这不会导致你提到的效果。

  2. 效果真实吗?用统计数据欺骗自己很容易。不是说你是,但确保所有您的运行都包含在结果中,并且所有其他效果(例如其他程序,活动,和您的监控程序都是在所有情况下都是一样的。我有多个监控程序,例如top,导致行为不同)。有一次,当缓存在数据库上的缓存时,应用程序的性能明显提高 - 同一数据库实例上的其他应用程序存在内存压力。

  3. 可能涉及操作系统和/或CPU。操作系统和CPU主动和被动地执行操作以提高主程序的响应能力,因为它从主要运行转变为主要等待I / O,反之亦然,包括:

    1. 操作系统在未使用时将内存分页到磁盘,在程序运行时返回RAM
    2. 操作系统将缓存经常使用的磁盘块,这又可以提高应用程序性能
    3. CPU指令和内存缓存填充活动程序的指令和数据
  4. Java应用程序对内存分页效果特别敏感,因为:

    1. 典型的Java应用程序服务器会将几乎所有可用内存预先分配给Java。大内存使应用程序本身对记忆效应更敏感
    2. 用于管理Java内存的世代垃圾收集器最终会在很多页面上创建新对象,因此对应用程序的每个请求都需要比其他语言更多的页面请求。 (这主要适用于未经过许多垃圾收集的“新”对象。提升为永久生成的对象实际上非常紧凑地存储)
    3. 由于大多数可用的物理内存都是在系统上分配的,因此内存总是存在压力,最大的,最近运行最少的应用程序是一个完美的候选页面。
    4. 考虑到这些因素,与内存需求较小的环境相比,页面未命中的可能性要大得多,因此性能也会受到影响。在Java闲置一段时间后,这些特别明显。

      如果使用Solaris或Mac,优秀的dTrace可以跟踪特定于应用程序的内存和磁盘分页。 JVM有许多dTrace挂钩,可用作启动和停止页面监控的触发器。

      在Solaris上,您可以使用大内存页(大小超过1GB)并将它们固定到RAM,这样它们就永远不会被分页。这应该消除上面提到的内存页面问题。请记住为磁盘缓存和其他系统/维护/备份/管理应用程序留出大量可用内存。我相信其他操作系统支持类似的功能。

      TL / DR:现代操作系统中当前运行的程序在几秒钟后似乎运行得更快,因为操作系统将程序和数据页从磁盘上恢复,将常用的磁盘页放入对于主程序,磁盘高速缓存和OS指令和数据高速缓存将趋于“温暖”。此效果不是JVM独有的,但由于典型Java应用程序和垃圾收集内存模型的内存要求而更加明显。