Java重复对象分配性能影响

时间:2017-01-01 23:59:07

标签: java performance garbage-collection allocation

为什么LinkedList比常规数组(没有新的分配)比big n慢10倍:

  Deque<Boolean> tail = new LinkedList<>();
  for (int i = 1; i <= n; i++) {
       tail.addFirst(true);
       tail.pollLast();
  }

我的第一个好处是gc时间,但只需3.5秒即可完成。 什么是找到背后原因的最佳方法?

1 个答案:

答案 0 :(得分:1)

  

找到背后原因的最佳方法是什么?

有很多方法:

  1. 将您的示例转换为适当的基准并使用分析器运行它。然后查看花费的时间。

  2. 查看您正在调用的LinkedList方法的源代码。

  3. 检查Javac编译器为您的代码和LinkedList代码生成的字节代码。

  4. 检查JIT编译器为您的代码和LinkedList代码生成的本机代码。

  5. (我会让你自己调查一下,因为我怀疑它会显示出任何特别意外的事情。)

      

    我的第一个猜测是gc时间,但仅在3.5秒内需要100毫秒。

    很可能大部分时间都是分配和初始化链表节点对象,以及列表方法的其他开销。

    如果GC确实需要在构建列表时运行,那么LinkedList情况下的GC开销会比数组情况稍大一些。但我怀疑实际发生的事情是GC实际上正在回收在代码加载和(可能)JIT编译期间创建的对象。在两种情况下,列表/数组构建期间产生的实际可收集垃圾量应为零。

    您的基准测试方法也可能会扭曲结果。例如,我注意到您的pollLast调用没有做任何有用的事情......关于构建列表。另一个问题可能是您不允许JVM预热效果。

    通常,您看到的10倍差异对应于Java列表与阵列性能的“接受的智慧”。如果您使用的是ArrayList而不是LinkedList,那么性能将更接近于裸阵列,尤其是如果您对ArrayList容量进行了很好的估算。