我正在使用JBoss 7.1.3以及以下Java,Linux版本......
[dave@mymachine ~]$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
[dave@mymachine ~]$ uname -a
Linux mymachine.mydomain.org 4.1.99-99.88.amzn1.x86_64 #1 SMP Fri Feb 5 23:44:22 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
我想弄清楚使用了多少堆(不是最大量,而是当前使用的是什么)。可悲的是,在我们的机器上,我无法访问jmap或jstat。所以我想使用“kill -3”进行堆转储。所以我先得到了老板程序的pid
[dave@mymachine ~]$ ps -elf | grep jboss
1 S root 1251 1 0 80 0 - 28870 - 07:03 ? 00:00:00 /bin/sh /etc/rc3.d/S84jboss start
4 S root 1254 1251 0 80 0 - 34424 - 07:03 ? 00:00:00 runuser -s /bin/bash jboss -c ulimit -S -c 0 >/dev/null 2>&1 ; LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=/var/run/jboss-as/jbos-as-standalone.pid /usr/java/jboss/bin/standalone.sh -c standalone.xml
4 S jboss 1255 1254 0 80 0 - 28271 - 07:03 ? 00:00:00 bash -c ulimit -S -c 0 >/dev/null 2>&1 ; LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=/var/run/jboss-as/jboss-as-standalone.pid /usr/java/jboss/bin/standalone.sh -c standalone.xml
0 S jboss 1256 1255 0 80 0 - 28272 - 07:03 ? 00:00:00 /bin/sh /usr/java/jboss/bin/standalone.sh -c standalone.xml
0 S jboss 1289 1256 3 80 0 - 603908 - 07:03 ? 00:18:26 /usr/java/default/bin/java -D[Standalone] -server -XX:+UseCompressedOops -Xms256m -Xmx1024m -XX:MaxPermSize=512m -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.server.default.config=standalone.xml -Dorg.jboss.as.logging.per-deployment=false -Dorg.jboss.boot.log.file=/usr/java/jboss/standalone/log/boot.log -Dlogging.configuration=file:/usr/java/jboss/standalone/configuration/logging.properties -jar /usr/java/jboss/jboss-modules.jar -mp /usr/java/jboss/modules -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone -Djboss.home.dir=/usr/java/jboss -Djbos.server.base.dir=/usr/java/jboss/standalone -c standalone.xml
0 S 602 21746 20632 0 80 0 - 27615 pipe_w 16:46 pts/1 00:00:00 grep --color=auto jboss
然后我跑了“杀-3”......
[dave@mymachine ~]$ sudo kill -3 1289 1256
但没有打印出来,也没有在当前目录中生成文件。如何使用当前约束生成堆转储?
我怀疑你无法访问jmap
,jstack
等优秀的可维护性工具的主要原因是它们不是openjdk-6-jre
或openjdk-7-jre
Linux软件包的一部分(我在这里假设debian发行版)。我不明白为什么会这样。在我看来,这些工具应该是JRE
的一部分,而不是JDK
。这是证明:
$> apt-file list openjdk-6-jdk | grep jmap
openjdk-6-jdk: /usr/lib/jvm/java-6-openjdk-amd64/bin/jmap
openjdk-6-jdk: /usr/lib/jvm/java-6-openjdk-amd64/man/ja_JP.eucJP/man1/jmap.1.gz
openjdk-6-jdk: /usr/lib/jvm/java-6-openjdk-amd64/man/man1/jmap.1.gz
$> apt-file list openjdk-6-jre | grep jmap
<nothing>
无论如何,要获得这些工具,您应该考虑使用JDK并使用sudo apt-get install openjdk-6-jdk
安装它们。这不仅可以获得最新的JDK 6版本(顺便说一下,非常老)。然后,您应该可以访问为我们提供堆转储的工具以供以后分析。
堆转储与线程转储非常不同,后者向您显示JVM线程正在执行的操作。获取线程转储的一种方法是将QUIT
信号发送到JVM进程(使用,就像你说的那样:kill -3
)。这将显示重定向JVM的stdout的任何位置的线程转储。一个(几乎)等效的工具是jstack
,它又是JDK包的一部分,而不是JRE包。
但是线程转储不是你需要的。你需要堆转储。所以,你需要jmap
。
除此之外,您可以使用必不可少的Linux top
命令估计JVM使用的实际内存。确保正确分析输出以估计JVM使用的堆大小。
如果您在JVM中遇到OutOfMemoryError
,那么您应该考虑使用-XX:+HeapDumpOnOutOfMemoryError
启动它,以便在抛出OOME
时,至少可以获得堆转储。但是这样,只有在堆空间用完后才能获得堆转储!
将-XX:HeapDumpPath = mpath / heapdump设置为java命令行上的可写目录或文件,以启动JBOSS。此路径/文件需要为JBOSS运行的用户写入,然后再次尝试kill -3选项。
http://five.agency/java-heap-dump/
您还可以使用应用程序中的HotSpotDiagnosticMXBean进行堆转储。