我有一个关于 Java 内存消耗的有趣问题。我有一个调用我的 Java 应用程序的本机 C++ 应用程序。
该应用程序基本上会进行一些语言翻译\解析一些 XML 并响应网络请求。应用程序的大部分状态不必保留,因此它充满了接受字符串参数并返回字符串结果的方法。
随着时间的推移,此应用程序继续占用越来越多的内存,并且有一段时间它开始占用接近 2 GB 的内存,这使我们怀疑某些 Hashtable 或静态变量的某处存在泄漏。经过仔细检查,我们没有发现任何泄漏。比较一段时间内的堆转储,显示 char[] 和 String 对象占用大量内存。
然而,当我们检查这些 char[]、字符串时,我们发现它们没有 GC 根,这意味着它们不应该是泄漏的原因。由于它们是堆的一部分,这意味着它们正在等待垃圾收集。在使用了各种工具 MAT\VisualVM\JHat 并浏览了很多这样的对象后,我使用了 yourkit 的试用版。Yourkit 直接给出数据说 96% 的 char[] 和 String 是不可达的。这意味着在进行转储时,堆中 96% 的字符串都在等待垃圾收集。
我知道 GC 运行很少,但是当您通过 VisualVM 检查时,您实际上可以看到它正在运行 :-( 而不是堆上一直有这么多未使用的对象。
IMO 这个应用程序永远不应该占用超过 400-500 MB 的内存,这是它在前 24 小时内停留的地方,但它会继续增加堆:-(
我正在运行 Java 1.6.0-25。
谢谢你的帮助。