【发布时间】:2018-06-11 14:43:25
【问题描述】:
我有一个从服务器读取 XML 响应的应用程序。 这很好用,直到我尝试阅读 ~200.000 个 XML 响应。当我达到那个神奇的数字时,处理时间会减少 10 倍。 当我让它运行时,JVM 有时会说 GC 占用了 90% 的 CPU 时间。所以我首先尝试优化我的代码——使用字段而不是局部变量,在我的字符串上使用实习生(因为我有很多副本)等等。
这有点帮助,但是在大约 100k 个 XML 文件之后它仍然很慢。然后我尝试使用 Visual VM 来查看发生了什么,我看到的是:
直到 18:02,一切正常。然后突然间垃圾收集器开始发疯,并窃取 CPU 时间,这反过来又稳定了内存消耗。如果我们达到堆的最大内存,我会理解这一点,但我已将最大堆大小设置为 8 GB。
此时并没有什么不同,它基本上是一个巨大的循环,一遍又一遍地做同样的事情。
发生了什么,在这种情况下我该怎么办?
【问题讨论】:
-
这个问题太笼统和模糊了。你制造了太多垃圾,你需要制造更少的垃圾。
-
我建议在 JFR 开启
-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath=path或类似的情况下运行。分析录音以查看内存中的内容。 -
我猜?您将这些 XML 响应保存在内存中的某个地方。
-
创建垃圾不一定是问题。 Azul 展示了他们的 JVM 处理在 700 cres 上运行的 700 个线程,在 500 GiByte 堆上创建 20 GiByte/s 的垃圾,甚至不费吹灰之力,这就是 10 年前的 VM 和 GC 技术。问题是旧垃圾。
-
正如@JörgWMittag 所说,垃圾不是问题 - 随心所欲地创建。但要确保它变成垃圾。查看 JFR 的输出并确定存在什么问题。可能就像在某事上调用
close()一样简单。
标签: java memory-management garbage-collection jvm heap-memory