当jmap进行内存转储时,我的java应用程序是否继续运行?
答案 0 :(得分:10)
您的申请已停止。获得准确的堆转储的唯一实用方法是在创建转储时停止所有应用程序活动。
这是“短暂”暂停还是“长时间”暂停取决于倾倒量。如果使用“-dump”,则将转储整个堆,包括无法访问的对象。如果使用“-dump:live”,则只会转储可到达的对象......但这也需要(至少)标记堆以确定哪些对象可以访问。
但是如果你要转储一个千兆字节大小的堆,那么期望用几分钟而不是几秒来测量暂停时间。
重新建议您可以避免使用fork来停止JVM,事实证明,分叉多线程进程可能会有问题:
然后是资源使用问题。
答案 1 :(得分:10)
我在生产机器上尝试执行此操作时出现问题,使用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 update
apt-get install gdb
...
获取您对
感兴趣的java进程的java进程IDJPS ...
使用该进程启动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 :(得分:4)
我会说你的程序会在进行内存转储时暂停。 内存转储是正在运行的程序的快照,因此jmap需要在读取内存时短暂锁定JVM。但是,要将转储文件发送回客户端,可以在单独的线程中完成,从而最大限度地减少暂停。