I have several Java processes and I am trying to manage the heap dumps created when OOM error occur. When I say manage I mean
The -XX:HeapDumpPath
on the command line doesn't give you any more flexibility than what you have already discovered. That is, you can either:
java_pidXXX.hprof
will be created in that directory.The relevant code in the HotSpot source is heapDumper.cpp. Reading it, it doesn't look for any "magic sequences" inside the given path:
That's it. No parsing of the path beyond determining if it's a directory or not.
The only flexibility you can add to it is to use the shell's abilities when you construct the name on the command line. That's why you may see some examples on the web that use something like name_`date`.ext
- this is processed by the shell, which substitutes `date`
with the current date once. That is, the file name will always have the date/time when the shell processed the command and started the JVM - not the date/time when the dump was created. If that's good enough for you - you can use that. Note that nowadays it's considered more acceptable to use the syntax name_$(date).ext
.
If you only need the date in order to be able to remove old files then you can remove them based on the file's last modification time (the Unix/Linux utility find
can help you with that). There is no need to have the date in the name.
The $(date)
(or `date`
) trick doesn't help you with the PID. The shell can also substitute the current PID if you use $$
- but it's the PID of the shell that processes the command line, not the JVM process itself. However, if you start your JAVA application using shell exec
command, it receives the same process ID as the shell it originated from, so you actually can use $$
to build your filename. Remember though that nothing after exec
will be executed from your script.
So you may try the dynamic change of the file name which @apangin suggested in his answer. Note, though, that it will probably be a little difficult to pinpoint the time of the dump itself, as you'll want to have the file name set before the OOM actually happens.
HeapDumpPath
is a manageable VM option. This means you can set it to whatever you want in runtime using JMX.
String pid = ManagementFactory.getRuntimeMXBean().getName();
pid = pid.substring(0, pid.indexOf('@'));
String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String fileName = "/tmp/heap_" + pid + "_" + date + ".dump";
HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(),
"com.sun.management:type=HotSpotDiagnostic",
HotSpotDiagnosticMXBean.class);
bean.setVMOption("HeapDumpOnOutOfMemoryError", "true");
bean.setVMOption("HeapDumpPath", fileName);