今天在使用idea调试我的代码的时候,后端突然终止运行了,并报错:
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000026a000002e1, pid=23292, tid=4916
JRE version: Java(TM) SE Runtime Environment (17.0.1+12) (build 17.0.1+12-LTS-39)
Java VM: Java HotSpot(TM) 64-Bit Server VM (17.0.1+12-LTS-39, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
Problematic frame:
C 0x0000026a000002e1
No core dump will be written. Minidumps are not enabled by default on client versions of Windows
If you would like to submit a bug report, please visit:
https://bugreport.java.com/bugreport/crash.jsp
The crash happened outside the Java Virtual Machine in native code.
See problematic frame for where to report the bug.
从来没有遇到过,直接懵了!大概记录一下错误是怎么出现的。
前情提要
我再通过前端发送一个axios请求,传递一个栅格图像文件(tif)给后端,后端接收之后,解析这个文件,提取出我要的信息返回展示。
之前测试的时候是可以实现的,但是忽略了一个情况,就是我的功能是前后一共要上传两次文件,之前都是单个测试的,现在一起测试发现,第二次的时候后端会直接终止,并报以上错误。
解决方法
大致翻译了一下,“无法写入核心转储文件。在 Windows 客户端版本上,默认情况下未启用小型转储文件。",完全不知道是啥,搜了一下大致是Java试图访问它不应该访问的内存,导致程序崩溃,于是打开具体的日志查看
日志里显示了错误的具体情况,红色位置,问题所在的帧是 0x0000026a000002e1
,它指向了一个C语言的函数或代码段。这个错误发生在 org.gdal.gdal.gdalJNI.delete_Dataset
方法。
于是大概明白了,我后端是通过封装GDAL的方法读取tif栅格数据的,这个方法前后调用了两次,第二次报错。而我涉及到关闭或者删除的地方在代码里之后最后释放资源
点进去看看
应该是这里有问题了,去查了一下帮助文档发现,Dataset里有一个delete方法,是释放资源,而Close方法没有解释
百度了一下,Close (dataset),它关闭了数据集并释放占用的资源,但是对象dataset并没有被摧毁,可以继续使用打开新的数据集
delete dataset,直接销毁对象,并在此过程中调用析构函数,释放该对象所占用的所有资源
猜测可能是我第二次调用方法时,没有销毁对象导致的0.0,改成delete后,报错消失。