gpt4 book ai didi

java - 旧代堆空间溢出

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:54:26 25 4
gpt4 key购买 nike

我在 Java 中遇到了一个非常奇怪的 GC 问题。我正在运行以下代码:

 while(some condition){
//do a lot of work...
logger.info("Generating resulting time series...");
Collection<MetricTimeSeries> allSeries = manager.getTimeSeries();
logger.info(String.format("Generated %,d time series! Storing in files now...", allSeries.size()));

//for (MetricTimeSeries series : allSeries) {
// just empty loop
//}
}

当我查看 JConsole 时,在每次循环迭代重新启动时,如果我手动强制 GC,我的旧代堆空间占用大约 90 MB 的大小。如果我取消注释循环,像这样

 while(some condition){
//do a lot of work...
logger.info("Generating resulting time series...");
Collection<MetricTimeSeries> allSeries = manager.getTimeSeries();
logger.info(String.format("Generated %,d time series! Storing in files now...", allSeries.size()));

for (MetricTimeSeries series : allSeries) {
// just empty loop
}
}

即使我强制刷新,它也不会低于 550MB。根据 yourKit 探查器,TimeSeries 对象可通过主线程的本地 var(集合)访问,就在 GC 重新启动新迭代之后......而且集合很大(250K 时间序列。)......Wyy 是这种情况发生了,我该如何“对抗”这种(不正确的?)行为?

最佳答案

是的,垃圾收集器可能很神秘..但它胜过管理你自己的内存;)

Collections 和 Maps 有一种方法可以使引用的停留时间比您可能喜欢的时间长,从而在您预期的时候阻止垃圾回收。正如您所注意到的,将 allSeries 引用设置为 null 本身会将其标记为垃圾收集,因此它的内容也可供获取。另一种方法是调用 allSeries.clear():这将取消所有 MetricTimeSeries 对象的链接,并且它们将免费用于垃圾收集。

为什么删除循环也可以解决这个问题?这是一个更有趣的问题。我很想建议编译器正在优化对 allSeries 的引用。但是你仍在调用 allSeries.size() 所以它不能完全 优化引用。

为了搅浑水,不同的编译(和设置)行为不同,并使用不同的垃圾收集器,而这些垃圾收集器本身的行为也不同。在没有更多信息的情况下,很难确切地说出幕后发生的事情。

关于java - 旧代堆空间溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13893136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com