我有一个 Java 应用程序 24/7 运行,它连接到 MySQL 服务器和 TimerTask(正在运行 Akka)。经过一周或更短的操作后,我遇到了 OutOfMemoryError,堆转储显示了一个包含超过 400 万个字符串的 LinkedHashMap,它们有一个 java.io.DeleteOnExitHook 的 GC 根,使用了 800 MB 的堆。
所有字符串都类似于/tmp/jar_cachexxxx.tmp
此问题在两台运行 OpenJDK Runtime Environment (build 1.8.0_101-b13) 的机器上是一致的。 JDBC 驱动程序是 maven“mysql-connector-java”版本 5.1.38 上提供的驱动程序,我使用的是连接池 BoneCP,版本 0.8.0。
有人知道这次泄漏吗?
更新 -- 2016 年 5 月 12 日
我们为项目更改了编译器后,问题已解决。我们注意到eclipse jar creator是唯一与jar cache有任何关系的东西,所以我们用maven编译项目后,内存泄漏就消失了。
最佳答案
这是一个长期存在且广为人知的错误,多年来已多次向 Sun/Oracle 报告。当前的错误编号是 JDK-4872014 .
问题是每次您使用退出时删除 API 时,文件都会存储到 HashMap
中。由于在长时间运行的服务器中,您的代码很少有意退出,因此如果您使用大量临时文件执行此操作, map 可能会无限制地增长。
从本质上讲,该 API 不适用于长时间运行的服务器,因为它并非真正打算以这种方式使用。如果您需要此功能,您需要自己实现并按计划运行清理,并通过某种方式了解哪些文件可以删除。
关于java - DeleteOnExitHook 上的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40119188/