关闭时无法从命令行[JFR][ERROR][1014.291]存储库中删除Java Flight Recorder(JFR)

关闭时无法从命令行[JFR][ERROR][1014.291]存储库中删除Java Flight Recorder(JFR),java,jfr,Java,Jfr,我正在学习Java飞行记录器的使用 我根据示例编译了一个java代码(添加类和导入,因为它没有编译出它们): import java.util.ArrayList; 导入java.util.List; 类TestFlightRecorder{ 公共静态void main(字符串[]args){ 列表项=新的ArrayList(1); 试一试{ while(true){ 添加(新对象()); } }捕获(OutOfMemory错误){ System.out.println(e.getMessage

我正在学习Java飞行记录器的使用

我根据示例编译了一个java代码(添加
导入
,因为它没有编译出它们):

import java.util.ArrayList;
导入java.util.List;
类TestFlightRecorder{
公共静态void main(字符串[]args){
列表项=新的ArrayList(1);
试一试{
while(true){
添加(新对象());
}
}捕获(OutOfMemory错误){
System.out.println(e.getMessage());
}
断言items.size()>0;
试一试{
睡眠(1000);
}捕捉(中断异常e){
System.out.println(e.getMessage());
}
}
}
然后我按照课程进行跑步:

C:\ProgramFiles\Java\jdk1.8.0\U 191\bin>Java -XX:+UnlockCommercialFeatures-XX:+F lightRecorder-XX:StartLightRecording=duration=200s,filename=c:\am\out\flight.j fr-cp c:\am\out TestFlightRecorder

紧接着输出:

开始录制1。结果将写入:

C:\AM\out\flight.jfr

java的Windows任务管理器中的内存使用率上升,然后在超过200秒后:

线程“main”java.lang.OutOfMemoryError中出现异常:java堆空间 在TestFlightRecorder.main(TestFlightRecorder.java:12)[jfr][ERROR][1014.291]上,无法在关闭时删除存储库

得到的
flight.jfr
大小为0字节。(当我使用simple hello world java类发出相同命令时,flight.jfr的大小为125Kb,其中包含“空”信息——我猜这是因为应用程序工作得如此之快,飞行记录还没有启动——而这个问题与空性无关)


对此类错误的Web搜索未显示结果。为什么会出错,我是否做了一些不正确的事情来录音?

艾伦的评论暗示了这一点:

OOMError可能会对JVM造成足够的中断,从而导致flightrecorder 不写


我以20秒而不是200秒的重新编码时间运行代码(在TaskManager中,我看到java内存使用量也在这段时间内增长到了2Gb的最大堆),并得到了与课程中所示类似的图形记录。因此,我认为当前问题已经解决了。

< P> java飞行记录器在应用程序结束时将转储写入java关机钩子中。如果没有足够的内存来产生转储,它将失败


发生此错误的原因是,当关闭挂钩线程试图删除文件时,JVM仍保留该文件

你的
线程.sleep
不应该在
while(true)
循环中吗?因为您的代码会冲向OOMError,这可能会中断JVM,导致flightrecorder无法将其“空信息”写入其日志文件,并显示您的错误saw@Aaron“空信息”可能是无关的,我写这篇文章是为了说明jfr通常在那个工作站上工作。至于OOM,course说,错误是应用程序想法的一部分,“我们的程序将对象插入列表,直到OutOfMemoryError发生。”如果我们只是将睡眠移动到循环中,据我所知,对于学习练习来说,内存增长太慢。你已经知道预期的结果了吗?因为否则“遇到OOM使FlightRecorder失败”似乎是预期的结论。实际上,我无法重现您的问题,每次运行代码时,我都会得到一些飞行记录数据,可能是因为不同的内存设置。尽管如此,我仍然建议您删除catch和thread.sleep,单独使用list init和
while(true)
循环就足以满足您的要求,并且在列表仍在范围内的情况下等待1秒可能会使情况恶化。@Aaron,感谢您对“OOMError可能会对JVM造成足够的干扰,导致flightrecorder无法写入“,我运行了设置为20秒的代码,得到了与课程类似的图形记录。所以我认为当前问题已经解决了。在我的命令中,JFR设置为200秒的时间帧。你写的是应用程序终止的案例。我看不出你的答案是如何适用的。如果你录制了一段持续时间,应用程序结束时将创建一个转储,我认为这是应用程序内存不足时发生的情况。一般来说,在内存不足的环境中,用Java编写的JFR代码可能会出现很多问题。JFR至少会创建另外两个同样分配内存的线程,如果它们在主线程之前运行到OOME中,事情就会破裂。
import java.util.ArrayList;
import java.util.List;

class TestFlightRecorder {
public static void main(String[] args) {
    List<Object> items = new ArrayList<>(1);
    try {
        while (true){
            items.add(new Object());
        }
    } catch (OutOfMemoryError e){
        System.out.println(e.getMessage());
    }
    assert items.size() > 0;
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        System.out.println(e.getMessage());
    }
}
}