我在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对象可以通过主线程的本地变量(集合)访问,在新迭代重新启动后进行GC之后...而且集合非常庞大(250K时间序列)。为什么会发生这种情况,如何“对抗”这种(错误的?)行为?