Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Out of memory automatic heap dump file name

Tags:

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

  • name the heap dump differently, based on the originating process
  • delete older heap dumps to preserve disk space

When dumping heap on OOM with

 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp 

the JVM creates a file with the following name java_pidXXXX.hprof in the specified /tmp folder (where XXXX is the PID of the process). Is there anyway to specify a different format where the PID and DATE are used to create the file name? After googling for an hour I tried myPrefix_$, {pid}, 'date'..etc. The only two things that work are

  1. not specify the file name and you get java_pidXXXX.hprof
  2. specify a static file name e.g. \tmp\OOM.hprof.

if the \tmp folder doesn't exist it doesn't get created, nor the heap dump gets created.

The one idea that could use is to add a command on OOM error

-XX:OnOutOfMemoryError="doSomething.sh %p" 

but I was trying to avoid it as I need to deploy the "doSomething.sh"

like image 788
Dan M Avatar asked Dec 03 '15 21:12

Dan M


People also ask

Where is Java heap dump file?

By default the heap dump is created in a file called java_pidpid. hprof in the working directory of the VM, as in the example above. You can specify an alternative file name or directory with the -XX:HeapDumpPath= option.

What is XX HeapDumpPath?

This HotSpot option is recognized by OpenJ9 for compatibility, and you can use it as an alias for -Xdump:directory=<path> . This option sets the directory for all VM dumps including heap dumps, Java™ dumps, and system dumps.

What is a Java heap dump file?

A heap dump is a snapshot of all the objects in the Java Virtual Machine (JVM) heap at a certain point in time. The JVM software allocates memory for objects from the heap for all class instances and arrays.

What is an Hprof file?

hprof files are heap dump of the memory of java-based processes. Huge hprof files most commonly indicate out of memory issues about the related processes. These hprof files can be configured at startup to track and monitor memory performance issues.


1 Answers

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:

  • Set a directory name, and then the default name java_pidXXX.hprof will be created in that directory.
  • Set a file name, and that file will be used as-is.

The relevant code in the HotSpot source is heapDumper.cpp. Reading it, it doesn't look for any "magic sequences" inside the given path:

  • It checks whether the given path is a directory. If so, uses that as a prefix, adds a file separator, and uses the default file name which is built up of hard-coded parts using a string format which is not under your control.
  • If it's not a directory, it just uses it as it is.
  • If it's not the first dump in this JVM's lifetime, it also appends a sequence number.

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.

like image 110
RealSkeptic Avatar answered Oct 12 '22 07:10

RealSkeptic