JVM 在执行 jmap 时是否停止?

2022-09-02 12:40:34

我的 java 应用程序在 jmap 进行内存转储时是否继续运行?


答案 1

我在尝试在生产机器上执行此操作时遇到了一个问题,使用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-get update

apt-get install gdb

...

获取您感兴趣的 java 进程的 java 进程 ID

jps ...

使用该进程启动 gdb 会话

gdb [pid] ...

然后生成核心文件:

gcore /tmp/jvm.core

结束 gdb 会话

分离退出

然后使用生成的核心文件来制作 hprof 文件:

sudo jmap -dump:format=b,file=jvm.hprof /usr/bin/java /tmp/jvm.core

然后(g)压缩文件并将其复制到您的计算机以进行进一步分析。


答案 2

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

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

但是,如果要转储千兆字节大小的堆,则希望暂停时间以分钟而不是秒为单位。


关于你可以通过使用fork来避免停止JVM的建议,事实证明,分叉一个多线程进程可能会有问题:

然后是资源使用问题。