jvm Java飞行记录器-连续滚动记录

b0zn9rqh  于 2022-11-07  发布在  Java
关注(0)|答案(2)|浏览(182)

问题

如何将滚动记录放入磁盘,并设置最长使用期限

上下文

当我的服务器出现问题时,我希望能够转储几个小时前的配置文件信息,并对其进行分析,以了解哪里出了问题。
1.因为我不知道什么时候事情会变坏,所以JDK应该不断地将事件保存到磁盘。
1.由于服务器不经常重新启动,为了避免文件无限增长,我需要设置某种上限(年龄或大小)。
因此,换句话说,我希望JDK将记录连续保存到磁盘,但删除较旧的文件/记录,使总量保持在某个阈值(年龄或大小)以下。
为此,我为Oracle JDK 1.8.0_144版本提供了以下选项:

-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-XX:StartFlightRecording
   name=<foo-bar>
-XX:FlightRecorderOptions
   defaultrecording=true   // what does this do even?
   disk=true
   maxage=1h // this is what I thought would solve my problem! 
   repository=<path-to-where-I-want-the-recording>
   maxchunksize=5M

我本以为设置maxage=1h只会在磁盘上保留最后1个小时的记录。但是没有!已经过去1天了,文件没有被限制。
与此同时,maxchunksize似乎可以工作。各种.jfr文件大约有5 M。其中有很多这样的文件,因为年龄上限没有被强制执行。
"我做错了什么"

vnzz0bqm

vnzz0bqm1#

我认为,问题是您正在开始两个录音,一个使用-XX:StartFlightRecording,另一个使用-XX:FlightRecorderOptions=defaultrecording=true
-XX:StartFlightRecording是无界的。我认为以下是适用于Oracle JDK 1.8.0_144和您的用例的选项:

-XX:+UnlockCommercialFeatures
-XX:FlightRecorderOptions=repository=<path>
-XX:StartFlightRecording=maxage=1h,name=<name>

-XX:+UnlockCommercialFeatures是必需的,因为JFR是Oracle JDK 8中的一个商业特性。从JDK 11开始,不再需要它。
对于JDK 8u40或更高版本,-XX:StartFlightRecoding不需要-XX:+FlightRecorder。JFR缓冲区现在是在启动第一个记录时设置的,而不是在启动JVM时设置的。如果使用defaultrecording=true启动记录,则仍需要-XX:+FlightRecorder
-XX:FlightRecorderOptions=defaultrecording=true做了很多事情,主要是因为历史原因,但只有在进行内存中记录时才需要。从JDK 9开始,从不需要该选项,并且已将其删除。
如果使用-XX:StartFlightRecording,则不需要-XX:FlightRecorderOptions=disk=true,maxage=1h,这是启动JFR的推荐方式。
除非您有问题,否则我会将maxchunksize保留为默认值(12MB)。这是JFR已经优化和测试过的块文件大小。

svujldwt

svujldwt2#

我接受Kire Haglin的答案。
为我在这个JDK上的工作增加了一些价值:

-XX:+UnlockCommercialFeatures
-XX:StartFlightRecording
  name=<foo-bar>
  maxage=12h
  dumponexit=true
-XX:FlightRecorderOptions
  dumponexitpath=<path-to-file>.jfr
  disk=true
  repository=<some-folder-path>

注意额外的参数dumponexitdumponexitpath,它们在我最初的问题中没有出现,我最终也需要它们。
经过反复试验,dumponexit必须存在于XX:StartFlightRecording参数中,而dumponexitpath必须存在于FlightRecorderOptions参数中,其他的排列似乎都不起作用。
还请注意,删除-XX:+FlightRecorderdefaultrecording=true(如Kire所建议的)* 仍然 * 有效。
我这样说是因为当发出命令jcmd <PID> JFR.check <name>时,我只得到了一个条目。

相关问题