我有一个在 Tomcat 7 上运行的 Java Web 应用程序,它似乎存在内存泄漏。在负载下(使用 JConsole 确定)时,应用程序的平均内存使用量随时间线性增加。内存使用量达到平稳期后,性能会显着下降。响应时间从约 100 毫秒到 [300 毫秒,2500 毫秒],所以这实际上导致了真正的问题。
我的应用程序的 JConsole 内存配置文件:
使用 VisualVM,我看到字符数组(即 char[])使用了至少一半的内存,并且大多数字符串(每个字符串的数量大致相同,300,000 个实例)是以下之一:“分配失败” 、“Copy”、“end of minor GC”,似乎都和垃圾回收通知有关。据我所知,该应用程序根本不监视垃圾收集器。VisualVM 找不到任何这些字符串的 GC 根,所以我很难找到它。
内存分析器堆转储:
我无法解释为什么内存使用率会如此稳定,但我有一个理论来解释为什么性能一旦下降就会下降。如果内存是碎片的,应用程序可能需要很长时间来分配一个连续的内存块来处理新的请求。
将其与内置的 Tomcat 服务器状态应用程序进行比较,内存会增加并趋于平稳,但不会像我的应用程序那样达到很高的“地板”。它也没有大量不可访问的 char[]。
Tomcat 服务器状态应用程序的 JConsole 内存配置文件:
Tomcat 服务器状态应用程序的内存分析器堆转储:
这些字符串可以分配到哪里,为什么它们没有被垃圾收集?是否有可能影响此的 Tomcat 或 Java 设置?是否有特定的软件包可能会影响这一点?