【问题标题】:Java performance gradually degradesJava 性能逐渐下降
【发布时间】:2020-05-04 18:07:09
【问题描述】:

我有一个 Java 类做这样的事情:

public void slowsDownOverTime() {
    for (int i=0 ; i<nIter ; i++) {
        BigObject bigObject = new BigObject();
        // some code here that populates big object ...
        CustomSerializer.write(bigObject);
    }
}

我观察到,随着代码的迭代,序列化程序编写所需的时间越来越长。启动时,序列化程序以毫秒为单位运行;经过几万次迭代后,运行需要几秒钟。

序列化程序写入的磁盘远未满,发生这种情况时,正在使用的 Java 堆空间远未接近其最大值。

我已尽可能减少在此周期中创建和销毁的对象的数量和大小。这基本上耗尽了我解决此类问题的工具包!

任何关于我如何理解和纠正逐渐性能下降的建议将不胜感激!

【问题讨论】:

  • 如果您定期调用System.gc()(例如所有10_000 迭代),问题是否仍然存在?
  • 只有CustomSerializer.write慢吗?您要附加到文件吗?
  • 这个问题可能与 write 方法内部发生的事情有关,而不是对象本身
  • 我同意@GotoFinal 所说的。但是,我要补充一点,找出正在发生的事情的最简单方法可能是使用分析器。一个简单的采样分析器应该可以解决问题,在 Java 中有很多可供选择的工具,例如 VisualVM(我相信它仍然随 JDK 一起提供)。
  • 您是否尝试过分析代码?

标签: java performance


【解决方案1】:

我认为,这是由遗漏的代码引起的(这里的一些代码填充了大对象......)。试试这个:

public void slowsDownOverTime() {
    BigObject bigObject = new BigObject();
    // some code here that populates big object ...
    for (int i=0 ; i<nIter ; i++) {
        CustomSerializer.write(bigObject);
    }
}

这将始终写入相同的对象,我希望这不会降低性能。

我认为遗漏的代码构建了一个不断增长的数据结构,bigObject 正在引用该结构。请记住,在序列化时,Java 会深入遍历所有依赖对象并序列化所有依赖对象。所以它会在每次迭代中写入越来越多的数据。这可能是影响性能和使用大量磁盘空间的原因。

【讨论】:

  • 从技术上讲,我认为您的意思是将填充大对象的代码放入循环中。您编写它的方式,每次写入相同的对象内容,而我的代码在顶部所做的是每次写入不同的内容。
  • 我更仔细地查看了代码,它与此示例显示的内容接近,以我的更正为模,而不是我最初的理解。 BigObject 实例在循环的每次迭代中都是相同的,但其内容会发生变化。我已将必要的更改量降至最低(即,许多 BigObject 成员从一次迭代到下一次迭代都是相同的——不仅仅是内容,还有实际的对象;所以创建/销毁成为 BigObject 的对象成员被最小化)。
  • 我的建议是(用于测试)将填充 bigObject 的代码放在循环之外。因此,您将在每次迭代中写入相同的数据。然后将此与您的版本进行比较。
  • 是否在执行序列化的循环之外填充了 bigObject 的测试(因此仍然序列化 nIter 次,但每次都是相同的对象)。在这种情况下,没有可检测到的减速。
【解决方案2】:

在对 jvisualvm 的分析器进行了很多无用的处理之后,我求助于添加了大量的日志记录。这给了我一个线索,即问题出在执行以填充 BigObject 的 Hibernate 操作中。我能够通过在检索到检索到的每个对象时将其逐出来解决性能问题。

我不是 Hibernate 专家,但我认为正在发生的事情是,即使对象超出了我代码中的范围(因此被垃圾收集),Hibernate 仍保留每个对象的副本在它的缓存中。然后当它执行下一次检索时,它将检索到的对象与所有缓存的对象进行比较。随着缓存数量的增加,此操作将花费越来越长的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-22
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多