分配延迟似乎很高,为什么?

Mat*_*att 8 java latency allocation jvm-hotspot low-level

我有一个在低延迟环境中运行的(java)应用程序,它通常处理大约600微米(+/- 100)的指令.当然,随着我们进一步进入微秒空间,您看到的成本延迟会发生变化,现在我们已经注意到2/3的时间用于分配2个核心域对象.

基准测试已将代码的违规部分与现有引用中的对象构造完全隔离,即基本上是一组引用(每个类中约15个)和一些新的列表,但请参阅下面关于确切测量的内容的注释这里.

每个人一直需要~100微米,这对我来说是莫名其妙的,我试图找出原因.一个快速的基准测试表明,一个类似大小的对象充满了字符串需要大约2-3微米到新的,显然这种基准充满了困难,但认为它可能是有用的基线.

这里有2个Q.

  • 如何调查这种行为?
  • 缓慢分配的解释是什么?

请注意,所涉及的硬件是Sun X4600上的Solaris 10 x86,带有8*双核opteron @ 3.2GHz

我们看过的东西包括

  • 检查PrintTLAB统计信息,显示一些缓慢的分配,因此不存在争用.
  • PrintCompilation建议这些代码中的一个不是JIT友好的,虽然Solaris似乎在这里有一些不寻常的行为(即对现代的linux,没有与solaris10类似的老式的Linux现在就可以进行替换)
  • LogCompilation ...有点难以解析,至少可以说这是一项持续的工作,到目前为止还没有什么明显的
  • JVM版本...在6u6和6u14中保持一致,尚未尝试过6u18或最新版本7

任何和所有的想法赞赏

关于各种帖子的评论摘要,试图让事情更清楚

  • 我测量的成本是创造,它通过生成器(像一个内置对象的总成本这些),其私人构造函数调用新的ArrayList几次以及对现有对象设置引用.测量的成本包括设置构建器的成本以及构建器到域对象的转换
  • 编译(通过热点)有明显的影响,但它仍然相对较慢(在这种情况下编译从100micros到~60)
  • 在我的天真基准测试中编译(通过热点)需要将分配时间从~2micros降低到~300ns
  • 延迟不会因年轻的收集算法(ParNew或平行清除)而有所不同

Ric*_*kNZ 2

内存分配可能会导致副作用。内存分配是否有可能导致堆被压缩?您是否检查过内存分配是否导致 GC 同时运行?

您是否单独计算过创建新 ArrayList 所需的时间?