持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
使用JPS命令,无法列出本地运行的java虚拟机;使用jvisualvm,提示"无法检测到本地java应用程序"
如果应用程序执行时间越来越长,或者如果操作系统的执行速度越来越慢,这说明可能存在内存泄露问题。换句话说,虚拟机持续分配内存,但是内存不再需要时却无法回收。最终,应用程序或系统运行耗尽内存,并且应用系统异常终止。
本章包含以下部分:
-
使用Flight Recorder调试内存泄露
-
理解OutOfMemoryError异常
-
系统Crash诊断
-
诊断Java代码中的内存泄露
-
诊断Native代码中的内存泄露
当JVM运行发生内存溢出并且由于OutMemoryError,一个以hs_oom_pid作为前缀(通常但是并不总是)的记录会写到JVM的启动目录。获取这些记录的另一种方式是在应用程序内存溢出之前使用jcmd工具进行dump,如下所示:
拿到这些记录后,使用JAVA_HOME/bin目录下的jfr工具打印Old Object Sample事件,这些事件包含了潜在的内存泄露信息。以下示例显示了PID为16276的应用程序的打印命令以及记录的输出:
解决办法
解决方法就比较简单了,更换下TMP文件夹的路径(所在磁盘是NTFS格式的)即可。这里需要提的是,如果在目标JVM运行时候,添加vm启动参数
-XX:+PerfBypassFileSystemCheck也可以解决问题
java -Xms20M -Xmx20M -Xmn10M -XX:+PerfBypassFileSystemCheck -cp classes/ direct.TestDirectMemo
原因
1、操作系统的临时文件目录所在的磁盘格式不是NTFS(可以通过echo %TMP%命令查看)
2、操作系统用户名含有下划线underscore(可以通过echo %username%查看)
检查了下,我的情况是第一种:TMP目录所在的磁盘是FAT32格式的