这是另一个"请告诉我如何强制Java垃圾收集器运行"的问题.在我们的申请中,我认为我们有充分的理由这样做.
这是一个服务器应用程序,通常有大约500万个活动对象.每5分钟一次,我们执行一项需要约60秒的分析任务.如果在分析运行时触发了完整的GC,则会有大约40M的活动对象.分析完成后,额外的35M对象将变为垃圾.服务器必须始终对请求保持响应(即使在分析运行时).
我们发现,如果在分析未运行时调用完整GC大约需要1.5秒,而在分析运行时大约需要15秒.不幸的是,我们的分配模式使得完整的GC通常在分析期间触发,即使分析仅在20%的时间运行.(每三次或第四次分析运行会触发完整的GC.)
如果老一代的可用空间低于某个阈值(5GB),我在开始分析运行之前添加了代码来调用备受诟病的System.gc().好处是非常可观的:我们得到1.5秒的暂停时间而不是15秒的暂停时间,我们将更多的垃圾带入讨价还价.但是,有时会忽略System.gc()调用,几分钟后,当GC自动触发时,我们会暂停15秒的暂停.
那么我的问题是:我们能做些什么来更有力地说服垃圾收集器运行?我们正在运行1.7.0_09-icedtea并使用Parallel GC.我想要(a)手动强制垃圾收集的可靠方法,或者(b)调整收集器的某种方式,以便它做出更智能的自动决策.(b)看起来很难,因为我不清楚收藏家如何发现我们的工作集以这种戏剧性的方式变化.
如果需要,我愿意诉诸大量的hackery; 这对我们来说是一个严重的问题.(我们可能会将CMS或G1压缩机视为替代方案,但我对CMS的吞吐量影响持怀疑态度,并且G1在我们使用的大字节数组面前表现不佳.)
附录:在生产中,我们迄今为止的经验是System.gc()通常会触发完整的垃圾收集; 至少,在我们称之为的情况下.(我们每10到30分钟只调用一次,堆有点但不完全充满垃圾.)能够更可靠地触发垃圾收集会很好,但它在大多数时候都在帮助我们.
我正在尝试构建一个JNI项目,但我似乎找不到JNI头文件(例如jni.h
).我已经从https://developer.apple.com/downloads/安装了"Java for Mac OS X 10.7 Developer Package" .
各种在线资源建议标题应该在诸如/System/Library/Frameworks/JavaVM.framework/Headers
或之类的位置/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/include
,但我无法在任何地方找到它们 - 安装程序似乎没有创建它们.
我看到其他JDK组件 - 例如,/System/Library/Frameworks/JavaVM.framework/Commands/javah
- 但不是JNI标头.有什么建议?
更新:technomage指出Apple现在安装JDK /Library/Java/JavaVirtualMachines
,JNI头文件位于/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/include/jni.h
.
但我仍然坚持我的实际目标,即为LevelDB构建JNI包装器(根据github.com/fusesource/leveldbjni的说明).为了将Maven指向正确的JDK,我添加/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/bin
到了PATH的前面,并将JAVA_HOME设置为/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
.经过一段时间的努力,Maven现在失败了:
[INFO] --- maven-hawtjni-plugin:1.5:build (default) @ leveldbjni-osx ---
[INFO] Extracting /Users/steve/leveldb/leveldbjni/leveldbjni/target/leveldbjni-99-master-SNAPSHOT-native-src.zip to /Users/steve/leveldb/leveldbjni/leveldbjni-osx/target/native-build-extracted
[INFO] executing: /bin/sh -c ./configure --disable-ccache --prefix=/Users/steve/leveldb/leveldbjni/leveldbjni-osx/target/native-build/target --with-leveldb=/Users/steve/leveldb/leveldb --with-snappy=/Users/steve/leveldb/snappy-1.0.3 --with-universal --with-leveldb=/Users/steve/leveldb/leveldb --with-snappy=/Users/steve/leveldb/snappy-1.0.3
...
[INFO] configure: JAVA_HOME was set, checking to see if it's a JDK we can use...
[INFO] checking if '/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home' …
Run Code Online (Sandbox Code Playgroud) 我们最近有一种情况,我们的一个生产JVM会随机冻结.Java进程正在烧毁CPU,但所有可见活动都将停止:没有日志输出,没有写入GC日志,没有响应任何网络请求等.进程将保持此状态直到重新启动.
原来,该org.mozilla.javascript.DToA类,某些输入调用时,会感到困惑,并呼吁BigInteger.pow着巨大的值(例如5 ^ 2147483647),这会触发JVM冻结.我的猜测是,一些大循环,可能是在java.math.BigInteger.multiplyToLen中,在循环中没有安全点检查的情况下进行了JIT.下次JVM需要暂停进行垃圾收集时,它会冻结,因为运行BigInteger代码的线程很长时间都不会达到安全点.
我的问题:将来,我如何诊断这样的安全点问题?杀-3没有产生任何输出; 我认为它依赖于安全点来生成准确的堆栈.是否有任何生产安全的工具可以从正在运行的JVM中提取堆栈而无需等待安全点?(在这种情况下,我真的很幸运,并设法抓住一组堆叠的痕迹BigInteger.pow被调用刚过,但在此之前它的工作它的方式到足够大的输入完全楔入JVM,没有运气中风,我我不确定我们怎么会诊断出这个问题.)
编辑:以下代码说明了问题.
// Spawn a background thread to compute an enormous number.
new Thread(){ @Override public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
BigInteger.valueOf(5).pow(100000000);
}}.start();
// Loop, allocating memory and periodically logging progress, so illustrate GC pause times.
byte[] b;
for (int outer = 0; ; outer++) {
long startMs = System.currentTimeMillis();
for (int inner = 0; inner < 100000; inner++) {
b = new byte[1000];
}
System.out.println("Iteration " …
Run Code Online (Sandbox Code Playgroud) 默认情况下,Heroku为(Ruby)应用程序的每个请求生成两条日志消息.在每种情况下,都有一些字段的含义不明显.首先,路由器消息(因为它出现在logplex中):
<158>1 2014-08-04T18:28:43.078581+00:00 host heroku router - at=info method=GET path="/foo" host=app-name-7277.herokuapp.com request_id=e5bb3580-44b0-46d2-aad3-185263641044 fwd="50.168.96.221" dyno=web.1 connect=0ms service=2ms status=200 bytes=415
大部分都是相当明显的,但我不知道<158>1
开头host
的时间,时间戳之后的字,以及-
后面的"路由器".
接下来,Web应用程序消息:
<190>1 2014-08-04T18:28:43.015630+00:00 host app web.1 - 50.168.96.221 - - [04/Aug/2014 18:28:43] "GET /foo HTTP/1.1" 200 12 0.0019
这与路由器消息具有相同的神秘性,再加上IP地址后的两个破折号.
有谁知道Heroku日志格式的完整文档?我在网上找到的所有资料都很模糊.