7

I have tried to take a heap dump using jcmd (from a git bash console window):

$ /c/Program\ Files/Java/jdk1.8.0_202/bin/jcmd 25156 GC.heap_dump filename=livetest-grindtohalt.hprof
25156:
Heap dump file created

However, the file does not seem to exist:

$ find -name livetest-grindtohalt.hprof

$

Where can I find it?

Robin Green
  • 32,079
  • 16
  • 104
  • 187
  • maybe you should specify a path for your find command before -name argument – arkantos Oct 23 '19 at 09:30
  • `find . -iname '*livetest-grindtohalt.hprof*'` doesn't find it either. I am assuming it is under the current directory, because that is the repository root in which both the jcmd command was run and process 25156 is running. – Robin Green Oct 23 '19 at 09:36
  • i understand and it's interesting. I'd give `find / ...` a try if it doesn't exhaust your machine's resources. – arkantos Oct 23 '19 at 09:52

3 Answers3

19

I had the same problem in windows.

jcmd 6232 GC.heap_dump filename=IShp1.hprof

it ran, said file created, but a search of c drive couldn't find it. Reran and got 'file exists'.

Tried with a path specified in filename, and a different file name,

jcmd 6232 GC.heap_dump filename=c:\temp\IShp2.hprof

This also got 'file exists'.

I conclude 'filename' is not being honored. Presumably jcmd is writing some internally-specified unknown file name to some unknown location, when the 'filename' is specified.

Instead

jcmd 6232 GC.heap_dump c:\temp\isHpdmp1.hprof

works and writes the file to the specified location. So presumably for *nix something like

jcmd 6232 GC.heap_dump /opt/temp/myHd.hprof 
RamPrakash
  • 1,687
  • 3
  • 20
  • 25
  • 5
    This answer is pure gold. Indeed, the "filename=" is a documentation error. When you specify that, jcmd creates the dump file named "filename", which is why subsequent invocations produce the "file exists" error (because the equal sign and all that follows are ignored). The correct invocation is giving the desired target path/name directly, without the filename= part. – volkerk May 21 '20 at 11:22
  • Is it possible to output this to an stdout? So we can stream it with scp. The thing is, sometimes in real life scenarios, the disk space is too low on servers, and storing it on vm is not an option – zookastos Aug 18 '22 at 00:51
  • Adding the filename=abc.hprof creates a file with the name "filename" in the current working directory of the Java process. – Avinash Ganta Oct 28 '22 at 16:30
9

The answer by Douglas Kretzmann sets you on the correct path to practical jcmd use. To answer the question from the original post, relative paths are resolved against the current working directory of the specified java process. So after

jcmd 6232 GC.heap_dump heap.hprof

you will be able to find heap.hprof in the directory output by

lsof -p 6232 | grep cwd
winf3red
  • 106
  • 1
  • 1
5

Literally upstream refuses to "fix" diagnostic for 4 years:

https://bugs.openjdk.java.net/browse/JDK-8177763 - Getting an hprof dump via jcmd could benefit from stronger option checking.

And official docs: https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks004.html presents incorrect examples, like:

Example 3-2 Create a Heap Dump using jcmd

jcmd <process id/main class> GC.heap_dump filename=Myheapdump

Just strip filename=.

Current working directory for dump is of PID process, not of jcmd! So use full path if you don't want to search for dump )) Full workflow:

mkdir dest/
chmod a+w dest/

sudo jcmd
1234 my.evil.app

sudo -u myuser -g mygrp jcmd 1234 GC.heap_dump $PWD/dest/myapp.hprof
gavenkoa
  • 45,285
  • 19
  • 251
  • 303