我在多核英特尔工作站上使用Win 7,Java 8。 我有这样的事情:
int SampleWeeksArray[]=new int[]{23,25,33},IdArray[]=new int[]{0,1,2};
for (int StartDay=25;StartDay<36;StartDay++)
for (int SampleWeeks : SampleWeeksArray)
for (int Id : IdArray)
for (float ValueFactor=0.08f;ValueFactor<0.13f;ValueFactor+=0.01)
{
DataDigester dataDigester=new DataDigester();
dataDigester.StartDay=StartDay;
dataDigester.SampleWeeks=SampleWeeks;
dataDigester.Id=Id;
dataDigester.ValueFactor=ValueFactor;
dataDigester.DoRun();
}
在dataDigester.DoRun()中,它读入一些文本数据文件,解析每一行并使用数组,向量和哈希映射进行一些统计,并使用ThreadPoolExecutor运行多个进程,然后将结果保存到文件中。
奇怪的是,每次运行DoRun()只需要10分钟,但在循环中,它以10分钟开始。但逐渐减慢到20,30分钟。对于每个DoRun()。
如果我在30分钟后停止循环,那么从我停止的地方重新开始,再过10分钟。并最终减慢到20,30分钟。再次。为什么?
我甚至在DoRun()之后添加了以下几行,但它没有提高速度,仍然放慢速度:
Thread.sleep(20*1000); // Rest for 20 seconds
System.gc();
在每个循环中,DataDigester dataDigester = new DataDigester()创建一个新对象,它应该在DoRun()之后被回收,为什么它会减慢?
我也从Windows任务管理器中注意到,随着循环的继续,内存使用率会上升。似乎Java以某种方式增加了某些东西并减速,所以在这种情况下如何将速度保持在10分钟的常数。对于循环中的每次运行?
答案 0 :(得分:1)
很难说不知道DataDigester是什么和做什么,但我能想到一个数字 可能的原因:
如果DataDigester.DoRun启动一个新线程 - 那么随着线程数量的增加, 每个线程可用的时间减少了。如果它使用硬件线程,那么 一旦你从每个硬件线程1到2个线程,时间将大大增加。
DataDigester可能具有它添加的静态结构,并且增长速度较慢 加入的越多,速度越慢
答案 1 :(得分:0)
只声明一个DataDigester
并将其重复用于所有循环,而不是创建成千上万的循环。
int SampleWeeksArray[]=new int[]{23,25,33},IdArray[]=new int[]{0,1,2};
DataDigester dataDigester;
for (int StartDay=25;StartDay<36;StartDay++)
for (int SampleWeeks : SampleWeeksArray)
for (int Id : IdArray)
for (float ValueFactor=0.08f;ValueFactor<0.13f;ValueFactor+=0.01)
{
dataDigester=new DataDigester();
dataDigester.StartDay=StartDay;
dataDigester.SampleWeeks=SampleWeeks;
dataDigester.Id=Id;
dataDigester.ValueFactor=ValueFactor;
dataDigester.DoRun();
}
}
}
}
这应该有助于您的垃圾收集问题和时间安排。