我们有一个Java webapp,我们从Java 1.5.0.19升级到Java 1.6.0.21
/usr/java/jdk1.6.0_21/bin/java -server -Xms2000m -Xmx3000m -XX:MaxPermSize=256m -Djava.awt.headless=true -Dwg.environment=production -Djava.io.tmpdir=/var/cache/jetty -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=31377 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/webapp -Dprogram.name=run.sh -Djava.endorsed.dirs=/opt/3p/jboss/lib/endorsed -classpath /opt/3p/jboss/bin/run.jar:/usr/java/jdk1.6.0_21/lib/tools.jar org.jboss.Main -c default
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样它应该预先分配2GB的堆并且最大值为3GB(为什么我们预先分配这么多是因为这个应用程序很古老而且设计很差,因此需要加载很多东西).我们在升级到1.6后最近看到的问题是,有时候内存会出现问题.虽然内存使用可能是一个应用程序问题,但JVM超过了堆的3GB最大设置.使用top我看到:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8449 apache 18 0 19.6g 6.9g 5648 S 4.0 84.8 80:42.27 java
Run Code Online (Sandbox Code Playgroud)
那么具有3GB堆,256MB permgen甚至一些开销的JVM怎么能消耗6.9GB呢?JVM中的错误可以通过升级到构建#35来修复吗?有什么东西缺少java中的内容可能会使用额外的内存?试着看看有没有人见过这个.
调试java.lang.OutOfMemoryError异常的最佳方法是什么?
当我们的应用程序发生这种情况时,我们的应用服务器(Weblogic)会生成堆转储文件.我们应该使用堆转储文件吗?我们应该生成Java线程转储吗?究竟有什么区别?
更新:生成线程转储的最佳方法是什么?是kill -3(我们的应用程序在Solaris上运行)杀死应用程序并生成线程转储的最佳方法吗?有没有办法生成线程转储但不杀死应用程序?