Java内存不足自动堆转储文件名 [英] Java Out of memory automatic heap dump file name

查看:150
本文介绍了Java内存不足自动堆转储文件名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个Java进程,我正在尝试管理发生OOM错误时创建的堆转储.当我说管理"时,我的意思是

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

  • 根据原始过程对堆转储进行不同的命名
  • 删除旧的堆转储以保留磁盘空间

使用以下命令在OOM上转储堆时

When dumping heap on OOM with

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

JVM在指定的/tmp文件夹(其中XXXX是进程的PID)中创建一个名称为java_pidXXXX.hprof的文件. 无论如何,在使用PID和DATE创建文件名时是否指定了其他格式? 谷歌搜索一个小时后,我尝试了myPrefix _ $,{pid},'date'.. etc. 唯一有效的两件事是

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. 不指定文件名,您将得到java_pidXXXX.hprof
  2. 指定静态文件名,例如\ tmp \ OOM.hprof.

如果\ tmp文件夹不存在,则不会创建它,也不会创建堆转储.

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

一个可以使用的想法是在OOM错误上添加一条命令

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

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

但是我试图避免这种情况,因为我需要部署"doSomething.sh"

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

推荐答案

命令行上的-XX:HeapDumpPath不能给您带来比已发现的更多的灵活性.也就是说,您可以:

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.
  • 设置文件名,该文件将按原样使用.

HotSpot源中的相关代码为 heapDumper.cpp .读取它,它不会在给定路径内寻找任何魔术序列":

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

  • 它检查给定路径是否为目录.如果是这样,请使用该前缀作为前缀,添加文件分隔符,并使用默认文件名,该默认文件名由硬编码部分组成,并且使用不受您控制的字符串格式.
  • 如果它不是目录,则按原样使用它.
  • 如果这不是此JVM生命周期中的第一个转储,它还会附加一个序列号.

就是这样.除了确定目录是否存在外,没有其他任何路径解析.

That's it. No parsing of the path beyond determining if it's a directory or not.

您可以添加的唯一灵活性是在命令行上构造名称时使用外壳程序的功能.这就是为什么您可能会在网络上看到一些使用name_`date`.ext之类的示例的原因-该示例由外壳处理,该外壳将`date`替换为当前日期一次.也就是说,文件名将始终具有外壳程序处理命令并启动JVM时的日期/时间,而不是创建转储时的日期/时间.如果这对您足够好-您可以使用它.请注意,如今使用name_$(date).ext语法被认为是更可接受的.

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.

如果只需要日期就可以删除旧文件,则可以根据文件的最后修改时间删除它们(Unix/Linux实用程序find可以帮助您).无需在名称中加上日期.

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.

$(date)(或`date`)技巧不能帮助您使用PID.如果您使用$$,则Shell也可以替换当前的PID,但是,它是 shell的PID,它处理命令行,而不是JVM进程本身.但是,如果使用shell exec命令启动JAVA应用程序,则该应用程序将收到与其原始外壳相同的进程ID,因此您实际上可以使用$$来构建文件名.请记住,尽管exec之后的任何内容都不会从您的脚本中执行.

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.

因此,您可以尝试动态更改@apangin在其答案中建议的文件名.但是请注意,确定转储本身的时间可能会有些困难,因为您希望在OOM实际发生之前设置文件名.

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.

这篇关于Java内存不足自动堆转储文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆