我有一个复杂的Java与Scala代码混合在一起读入输入文件并在逐行处理行时创建大量数据结构,包括从输入开始长度为10的所有子串的哈希表。 / p>
我最初使用-Xmx4g
开关运行代码,代码在返回OOM错误之前花了 20小时,并且没有完全通过文件。
然后我使用-Xmx32g
运行代码,代码在 8分钟中处理文件中的所有行,然后继续处理已读取的数据结构。 8分钟后,Java使用的驻留内存约为21GB。
我的问题是:为什么Java在8分钟内没有返回OOM错误?这20小时做了什么?
答案 0 :(得分:3)
根据您的描述,我愿意打赌您遇到的OutOfMemoryError标记为“java.lang.OutOfMemoryError:超出GC开销限制”。独立如果我的赌注是正确的,情况的描述与下面发生的事情完全匹配:
要检测此类情况,您可以打开GC日志(例如-verbose:gc或-XX:+ PrintGCDetails)并密切关注暂停时间。
答案 1 :(得分:1)
垃圾收集是非确定性和复杂的。这与JIT编译等其他内容相结合,使得精确的内存使用模式难以预测和复制。
你提到它包括Scala?这让事情变得更有趣。 "很好"功能构造可能产生比它看起来更多的垃圾。即使像Option-s中包装对象这样的小东西也需要额外的内存来清理。
答案 2 :(得分:0)
Java有一个垃圾收集器线程。如果它发现它可以收集足够的垃圾以释放空间,那么它就会这样做。
因此,我建议使用可视化虚拟机并监控下次垃圾收集所花费的时间。