我正在学习Java飞行记录器使用java-flight-recorder-monitoring的课程。
我从示例中编译了一个 java 代码(添加class
和imports
,因为它没有编译它们(:
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());
}
}
}
然后我按照课程运行:
C:\Program Files\Java\jdk1.8.0_191\bin>java -XX:+解锁商业功能 -XX:+F 灯光记录器 -XX:开始飞行记录=持续时间=200s,文件名=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 堆空间 at TestFlightRecorder.main(TestFlightRecorder.java:12( [jfr][ERROR][1014.291] 无法在关闭时删除存储库
生成的flight.jfr
大小为 0 字节。(当我使用简单的 hello world java 类发出相同的命令时,flight.jfr 的大小为 125Kb,里面有"空"信息 - 我想这是因为应用程序运行得如此之快 飞行记录尚未开始 - 这个问题不是关于空虚(。
网络搜索此类错误没有结果。为什么出错,我做错了什么来录音吗?
JavaFlight Recorder 在应用程序结束时将转储写入 Java 关闭钩子中。如果没有足够的内存来生成转储,它将失败。
发生此错误的原因是,当关闭钩子线程尝试删除该文件时,该文件仍由 JVM 持有。
由Aaron的评论暗示:
OOMError 可能会破坏 JVM,以至于飞行记录器 写入失败
我以 20 秒而不是 200 秒的重新编码时间运行代码(在任务管理器中,我看到 java 内存使用量也在大约那个时候增长到 2Gb 的最大堆(,并得到了与课程中类似的图表记录的结果。所以我认为当前的问题已经解决了。