控制台中的错误信息如下:
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000003aec715, pid=12424, tid=0x0000000002260
JRE version: Java(TM) SE Runtime Environment (8.0_241-b07) (build 1.8.0_241-b07)
Java VM: Java HotSpot(TM) 64-Bit Server VM (25.241-b07 mixed mode windows-amd64 compressed oops)
Problematic frame:
C [pLcommpro.dll+0xc715]
Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
An error report file with more information is saved as:
C:\Users\11193574\Desktop\smartarea\hs_err_pid12424.log
If you would like to submit a bug report, please visit:
http://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.
下面把尝试过的排查方法都记录一遍。这些方法不一定能解决所有情况,但说不定对你有用。
1. 尝试添加 -XX:+CreateMinidumpOnCrash
个人认为最关键的是这一句报错:
Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
无法写入核心转储。默认情况下,在客户端版本的 Windows 上不启用小型转储
要让 HotSpot VM 在 client 版 Windows 上写出 minidump,可以先在配置文件 idea64.exe.vmoptions(位置:IDEA 安装目录的 bin 文件夹中)里加上:
-XX:+CreateMinidumpOnCrash
这样 HotSpot VM 在 crash 时就会调用 Windows 的 MiniDumpWriteDump() 函数写出 minidump。
改完重启 IDEA,等一段时间观察效果。崩倒是没再立刻崩,但也没看见什么 minidump 文件。十分钟过去,项目暂时还活着,我一度以为解决了。结果还是自己挂了,呜呜呜。
2. 降低 JDK 版本
看来重点可能不在 minidump,而是这部分信息:
JRE version: Java(TM) SE Runtime Environment (8.0_241-b07) (build 1.8.0_241-b07)
Java VM: Java HotSpot(TM) 64-Bit Server VM (25.241-b07 mixed mode windows-amd64 compressed oops)
查了一些教程,决定试试降低 JDK 版本。当前 JDK 是 1.8.0_241,看看有没有其他小版本可用。
如果你也需要下载旧版本 JDK,别去各种奇怪的网站,直接从 Oracle 官网就能下历史版本。可以参考:从官网下载历史版本的 Java - DbWong_0918 - 博客园(cnblogs.com)。
下载 1.8.0_191 版本安装,配置好环境变量,再把 IDEA 项目里使用的 JDK 切换过去,重启项目。
等了半小时,还没挂,本来以为成功了。结果还是挂了,我真的……@#¥%……
师傅说之前调过 JVM 参数后好了很多,那就继续试。
3. 在 IDEA 中修改 JVM 参数
参考了一些做法,在虚拟机选项中添加:
-XX:CompileCommand=exclude,org/hibernate/cfg/annotations/SimpleValueBinder,setType
重新运行试试。还是会崩,不过存活时间明显变长,能撑一小时左右了。
4. JVM 内存调优
继续进行 JVM 调优,把堆大小设置为:
-Xms512m -Xmx1024m
重新运行后,存活时间明显拉长,放一晚上都没出问题。但是修改完代码重启项目时,不到半分钟又自己崩了。难顶啊兄弟们。
5. Tomcat 和环境版本匹配
要保证 Tomcat 和使用的DLL版本是一致的。首先在命令行 cd 到 Tomcat 安装目录的 bin 文件夹下,然后直接运行 version 相关命令,就能在输出信息里看到对应版本。
不过说实话,我这边本来就一致,所以这步对我来说没起什么作用。

6. GC 回收问题导致的内存溢出
看了看日志,怀疑是 GC方面的问题。对日志的解读可以参考 JVM 崩溃的原因及解决,官方也有 Oracle 的参考文档。
先确认自己用的是哪种 GC。直接在命令行输入:
java -XX:+PrintCommandLineFlags -version
得到如下信息:
-XX:InitialHeapSize=268427072
-XX:MaxHeapSize=4294833152
-XX:+PrintCommandLineFlags
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:-UseLargePagesIndividualAllocation
-XX:+UseParallelGC
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
其中 -XX:+UseParallelGC 说明新生代使用 Parallel GC,老年代使用 Serial Old(串行收集器)。看起来默认就是这种 GC 组合。
在项目启动配置(运行 → 编辑配置 → 环境 → 虚拟机选项)中添加:
-XX:+UseParallelOldGC
把老年代的垃圾收集器也配置成并行收集。重启项目试试,可惜还是不行。
7. 代码问题排查
这条基本可以排除——项目是已经上线的,代码层面不该有太大问题,否则也不会随机时间报错。
8. plcommpro.dll 文件是否有问题?
从 Problematic frame: C [pLcommpro.dll+0xc715] 大概能看出,问题出在 plcommpro.dll 这个文件上。不过这个文件就算有问题也不太敢随便动,晚点再自己研究。
以上就是我尝试过的所有方法。虽然问题还没完全解决,但服务存活时间已经比最开始长了很多。这次排查过程记录在云栈社区,后面继续摸索,希望能找到彻底解决的方式。