当 jmap 进行内存转储时,我的 java 应用程序是否继续运行?
3 回答
我在使用 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进程的java进程id
日本人...
启动与该进程的 gdb 会话
gdb [pid] ...
然后生成核心文件:
gcore /tmp/jvm.core
结束 gdb 会话
分离退出
然后使用生成的核心文件制作一个 hprof 文件:
sudo jmap -dump:format=b,file=jvm.hprof /usr/bin/java /tmp/jvm.core
然后 (g) 压缩文件并将其复制到您的计算机以进行进一步分析。
您的应用程序已停止。获得准确堆转储的唯一实用方法是在创建转储时停止所有应用程序活动。
这是“短暂”暂停还是“长时间”暂停取决于倾倒了多少。如果您使用“-dump”,那么您将转储整个堆,包括无法访问的对象。如果您使用“-dump:live”,您只会转储可访问的对象......但这也需要(至少)标记堆以找出哪些对象是可访问的。
但是,如果您要转储千兆字节大小的堆,则预计暂停时间以分钟而不是秒为单位来衡量。
重新建议您可以通过使用 fork 来避免停止 JVM,事实证明,分叉多线程进程可能会出现问题:
然后是资源使用问题。
我会说您的程序在进行内存转储时会短暂暂停。内存转储是您运行程序的时间快照,因此 jmap 需要在读取该内存时短暂锁定 JVM。然而,要将转储文件发送回客户端,可以在单独的线程中完成,从而最大限度地减少暂停。