Java程序运行一段时间后变慢了

我有一个java程序,这是一个典型的机器学习algorithm,通过一些方程更新一些参数的值:

for (int iter=0; iter<1000; iter++) { // 1. Create many temporary variables and do some computations // 2. Update the value for the parameters } 

更新参数的计算相当复杂,我必须创build很多临时对象,但是它们不会被引用到循环之外。 循环中的代码是CPU密集型的,不能访问磁盘。 这个程序加载了一个相对较大的训练数据集,因此,我向JVM授予了10G内存(-Xmx10G),远远大于它所需要的(“top”命令或窗口任务pipe理器在〜6G的峰值)。

我在几台安装了Sun热点JDK / JRE 1.8的Linux机器(centos 6,24G内存)和一台窗口机器(win7,12G)上进行了testing。 我没有指定除-Xmx之外的其他JVM参数。 这两台机器都专门用于我的程序。

在Windows中,我的程序运行良好:每次迭代使用非常相似的运行时间。 但是,在所有的centos机器上运行的时间是奇怪的。 它最初运行正常,但是在第7次/第8次迭代时会显着减慢(减慢〜10倍),然后在每次迭代中保持减速〜10%。

我怀疑这可能是由Java的垃圾收集器造成的。 因此,我使用jconsole来监视我的程序。 次要GC在两台机器上都经常发生,这是因为程序在循环中创build了许多临时variables。 此外,我使用“jstat -gcutil $ pid $ 1s”命令并捕获了统计信息:

Centos: https ://www.dropbox.com/s/ioz7ai6i1h57eoo/jstat.png ? dl = 0

窗口: https : //www.dropbox.com/s/3uxb7ltbx9kpm9l/jstat-winpng.png?dl = 0

[编辑]但是,两种机器的统计数据差别很大:

  1. 窗口上的“S1”在0到50之间快速跳转,而在centos上保持“0.00”。
  2. 窗口上的“E”从0到100变化非常迅速。当我每秒打印一次统计数据时,屏幕截图没有显示其增量为100.但是,“E”增加得慢到100,然后减less到100 0,并再次增加。

我的程序的怪异行为似乎是由于Java GC? 我是Java性能监视器的新手,并没有一个好主意来优化GC参数设置。 你有什么build议吗? 非常感谢你!

我很抱歉张贴这个答案,但我没有足够的评分来评论。

如果你认为这是一个GC相关的问题,我会改变它的垃圾1收藏家-XX:+ UseG1GC

我发现这个简短的解释: http : //blog.takipi.com/garbage-collectors-serial-vs-parallel-vs-cms-vs-the-g1-and-whats-new-in-java-8/

你可以运行你的软件下分析? 尝试使用jprofiler,VisualVM甚至netbeans分析器。 它可以帮助你很多。

我注意到你有自己的封装的矢量和矩阵。 也许你也花费了太多的内存。 但我不认为这是问题。

再次对不起作为评论的贡献。 (这会更合适)

给Java(或任何垃圾收集语言)太多的内存对性能有不利影响。 实时(被引用的)对象在内存中变得越来越稀疏,导致从主内存中更频繁地获取内存。 请注意,在您向我们展示的示例中,更快的窗口比Linux更快速更完整的GC – 但GC循环(特别是全部gcs)通常对性能不利。

如果运行训练集不需要特别长的时间,那么可以尝试使用不同的内存分配进行基准测试。

一个更激进的解决方案,但应该有一个很大的影响是通过回收池中的对象来消除(或尽可能减少)循环内的对象创建。

我会考虑在循环之外声明变量,以便mem分配完成一次并完全消除GC。

首先,在循环之外声明变量以避免Garbace收集是一种常见的最佳做法。 正如“Wagner Tsuchiya”所说的那样,如果你对GC有疑问的话,可以尝试运行一个profiler。 如果你想在GC调整的一些技巧,我发现不错的blogpost 。

您可以尝试每次重复调用System.gc()来查看性能是上升还是下降。 这可能会帮助您将其缩小到某些以前的答案诊断。

如果GC时间是几百毫秒(如屏幕截图所示),则GC可能不是问题。 我建议你看看锁争用和可能IO使用探查器(Netbeans是伟大的)。 我知道你说你的程序做了很少的IO,但是通过分析(就像调试一样),你必须删除所有的假设,然后一步一步来。

根据我的经验,JAVA需要足够的内存和2个CPU。 否则当GC开始运行时,CPU使用率会非常大。