Java JVM在执行jmap时是否已停止?

Java JVM在执行jmap时是否已停止?,java,memory,memory-leaks,jmap,Java,Memory,Memory Leaks,Jmap,jmap进行内存转储时,我的java应用程序是否继续运行?您的应用程序已停止。获得准确堆转储的唯一实用方法是在创建转储时停止所有应用程序活动 这是一个“短暂”的暂停还是一个“长时间”的暂停取决于倾销的数量。如果使用“-dump”,则将转储整个堆,包括无法访问的对象。如果您使用“-dump:live”,您将只转储可访问的对象。。。但这也需要(至少)标记堆,以确定哪些对象是可访问的 但是,如果您正在转储一个千兆字节大小的堆,那么暂停时间应该以分钟而不是秒为单位 有人建议您可以通过使用fork避免停

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

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

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

但是,如果您正在转储一个千兆字节大小的堆,那么暂停时间应该以分钟而不是秒为单位


有人建议您可以通过使用fork避免停止JVM,但事实证明,对多线程进程进行fork可能会有问题:


然后是资源使用问题。

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

我在生产机器上尝试使用jmap创建hprof文件时遇到了一个问题,这花了很长时间,并且自然地将java webapp锁定了很长时间

我找到了这个页面:

这说明您还可以使用gdb(在linux系统上)转储java进程的核心

有了这个核心文件,您就可以在一个单独的过程中生成hprof文件进行分析,从而防止java服务器进程被中断这么长时间。如果您使用jmap运行相同的操作,将会发生这种情况

总结如下:

下载并安装gdb

apt获取更新

apt-get-install-gdb

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

太平绅士

使用该进程启动gdb会话

gdb[pid]

然后生成核心文件:

gcore/tmp/jvm.core

结束gdb会话

分离 退出

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

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


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

即使今天大多数/所有JVM都是这样做的,我也不确定这是“获得准确堆转储的唯一方法”。您还可以
fork
并从for子进程执行堆转储。这显然会占用大量的内存来进行写时复制,但如果您边写边释放页面,可能不会占用2倍的内存。@Ramon。将“唯一方式”更改为“唯一实用方式”。@StephenC对于GB+大小的堆,您是否希望转储需要几分钟甚至更多时间?看起来堆文件的增长速度非常慢,而且需要相当长的时间。@AHungerArtist-我希望它会相对较快。但是,文件系统速度慢或没有足够的物理内存(与JVM的vmem大小相比)可能会导致较长的转储时间。我在20分钟前启动了一个7 GiB的转储,其中
jmap
仍在运行。。。这是在Windows Server 2012 R2.WayBackMachine上原始文章的快照