2011-03-13 229 views

回答

6

您的应用程序已停止。获得准确堆转储的唯一实用方法是在转储创建时停止所有应用程序活动。

这是“短暂”暂停还是“长时间”暂停取决于倾倒的程度。如果您使用“-dump”,那么您将转储整个堆,包括无法访问的对象。如果您使用“-dump:live”,则只会转储可到达的对象......但这也需要(至少)标记堆以确定哪些对象可到达。

但是,如果你倾销一个千兆字节大小的堆,期望暂停时间以秒为单位而不是毫秒来衡量。


回复,你可以避开使用叉子停止JVM的建议,事实证明,派生一个多线程程序可能会出现问题:

然后就是资源ce使用问题。

+2

“否”=“它没有停止”或否=“它不会继续运行”? – meriton 2011-03-13 02:53:52

+0

即使这是大多数/所有JVM今天的做法,我不确定这是“获得准确堆转储的唯一方法”。你也可以'fork'并为子进程执行堆转储。这显然会在写入时使用大量内存,但如果您随意使用免费页面,则可能不会多达2倍。 – Ramon 2015-01-25 18:42:31

+0

@Ramon。将“唯一的方式”改为“唯一可行的方式”。 – 2015-01-25 23:24:30

3

我会说你的程序在暂停内存转储时暂停。 内存转储是您正在运行程序的快照,因此在读取内存时,jmap需要暂时锁定JVM。然而,要将转储文件发送回客户端,可以在单独的线程中完成,从而最大限度地减少暂停。

5

我在试图在生产机器上执行此操作时遇到了问题,它使用jmap创建hprof文件,并将年龄自然锁定java webapp。

我找到了这个网页:

http://blogs.atlassian.com/2013/03/so-you-want-your-jvms-heap/

对此解释称,您还可以使用gdb的(在Linux系统上)转储Java进程的核心。

通过这个核心文件,您可以在单独的进程中生成用于分析的hprof文件,以防止java服务器进程被长时间打断。如果您要使用jmap运行相同的操作,会发生什么情况。

总结:

下载安装GDB

apt-get的更新

的apt-get安装GDB

...

得到的java程序你感兴趣

JPS 的java进程ID ...

与过程

GDB [启动GDB会话pid] ...

然后生成核心文件:

的gcore /tmp/jvm.core

结束GDB会话

分离 退出

然后用核生成文件以生成hprof文件:

须藤JMAP -dump:格式= B,文件= jvm.hprof的/ usr/bin中/ JAVA /tmp/jvm.core

然后(克)ZIP文件起来,并将其复制到计算机中进一步分析。