为什么多进程内Java进程的速度会随着速度的降低而减慢?

时间:2014-06-22 17:07:58

标签: java performance loops

我在多核英特尔工作站上使用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分钟的常数。对于循环中的每次运行?

2 个答案:

答案 0 :(得分:1)

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

  1. 如果DataDigester.DoRun启动一个新线程 - 那么随着线程数量的增加, 每个线程可用的时间减少了。如果它使用硬件线程,那么 一旦你从每个硬件线程1到2个线程,时间将大大增加。

  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();
            }
        }
    }
}

这应该有助于您的垃圾收集问题和时间安排。