我在多核Intel工作站上使用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分钟。对于循环内的每次运行?

最佳答案

不知道DataDigester是什么和做什么是很难说的,但是我可以想到一个数字
可能的原因:


如果DataDigester.DoRun启动了一个新线程-那么随着线程数的增加,
每个线程可用的时间减少。如果利用硬件线程,则
每个硬件线程从1个线程转到2个线程,时间将大大增加。
DataDigester可能具有添加的静态结构,并且增长缓慢且
加得越慢

08-03 18:44