我正在运行一个Java程序,比如program.jar,它带有一个"小"初始堆(1gb)和一个"大"初始堆(16gb).当我用小的初始堆运行它,即
java -jar -Xms1g -Xmx16g program.jar
Run Code Online (Sandbox Code Playgroud)
程序在12秒内终止(多次运行平均).相反,当我用大的初始堆运行它,即
java -jar -Xms16g -Xmx16g program.jar
Run Code Online (Sandbox Code Playgroud)
程序在30秒内终止(多次运行平均).
我从SO的其他问题中了解到,一般来说,大堆可能会导致过多的垃圾收集,从而减慢了程序的速度:
但是,当我使用flag运行program.jar时-verbose:gc,不会报告任何具有大型初始堆的gc-activity.初始堆很小,在开始测量时间之前,在程序的初始化阶段只有一些gc活动.因此,过多的垃圾收集似乎并未澄清我的观察结果.
为了让它更混乱(至少对我而言),我有一个功能相同的程序,比如program2.jar,它具有与program.jar相同的输入输出行为.主要区别在于program2.jar使用的效率低于program.jar,至少就内存而言(无论program2.jar在时间上效率是否也低,实际上我正在尝试确定).但无论我是使用小的初始堆还是大的初始堆运行program2.jar,它总是在大约22秒内终止(包括大约2-3秒的gc-ing).
所以,这是我的问题:(怎么样)大堆可以减慢程序,放弃过多的gc-ing?
(这个问题可能看起来类似于Georg在" Java慢大堆 "中的问题,但他的问题与堆无关.在我的情况下,我觉得它必须与堆有关,因为它是唯一的program.jar的两次运行之间的差异.)
以下是一些可能相关的细节.我正在使用Java 7,OpenJDK:
> java -version
java version "1.7.0_75"
OpenJDK Runtime Environment (rhel-2.5.4.0.el6_6-x86_64 u75-b13)
OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)
Run Code Online (Sandbox Code Playgroud)
我的机器有两个E5-2690V3处理器(http://ark.intel.com/products/81713)在两个插槽中(超线程和Turbo Boost禁用)并且有足够的内存(64gb),其中大约一半是免费的在运行程序之前:
> free
total used free shared buffers cached
Mem: 65588960 31751316 33837644 20 154616 23995164
-/+ buffers/cache: 7601536 57987424
Swap: 1023996 11484 1012512
Run Code Online (Sandbox Code Playgroud)
最后,程序有多个线程(大约70个). …