什么是 StubRoutines::jbyte_disjoint_arraycopy

St.*_*rio 1 java jvm jmh

我正在测量一些单线程方法调用(用 Scala 编写)并想要分析基准测试。这是它的样子(省略了实现细节)

@State(Scope.Benchmark)
class TheBenchmarks {

    var data: Array[Byte] = _
    @Param(Array("1024", "2048", "4096", "8192"))
    var chunkSize: Int = _

    @Setup
    def setup(): Unit = {
        data = //get the data
    }

    @Benchmark
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    @BenchmarkMode(Array(Mode.AverageTime))
    def takeFirstAvroRecord(bh: Blackhole): Unit = {
      val fr = //do computation with data and chunk size
      bh.consume(fr)
    }

}
Run Code Online (Sandbox Code Playgroud)

好吧,我得到了一些结果并想理解它,但 -prof perfasm我有点不清楚它的输出。首先:

....[Hottest Regions]...............................................................................
 44.20%   40.50%        runtime stub  StubRoutines::jbyte_disjoint_arraycopy (205 bytes) 
  6.78%    1.62%         C2, level 4  cats.data.IndexedStateT$$Lambda$21::apply, version 1242 (967 bytes) 
  4.39%    0.79%         C2, level 4  my.pack.age.Mclass::cut0, version 1323 (299 bytes) 
Run Code Online (Sandbox Code Playgroud)

....[Hottest Methods (after inlining)]..............................................................
 44.20%   40.50%        runtime stub  StubRoutines::jbyte_disjoint_arraycopy 
  8.40%    3.93%         C2, level 4  cats.data.IndexedStateT$$Lambda$21::apply, version 1242 
  5.76%    2.67%         C2, level 4  my.pack.age.Mclass::cut0, version 1323 
Run Code Online (Sandbox Code Playgroud)

我找到了一些关于jbyte_disjoint_arraycopy. 这里声明如下。

StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, &entry,
                                                                           "jbyte_disjoint_arraycopy");
Run Code Online (Sandbox Code Playgroud)

从方法的来源来看,generate_disjoint_byte_copy它看起来像是一个汇编代码生成的东西......我可以猜测它是一些内在的数组副本x86......

问题:您能否解释一下StubRoutines是什么导致了它成为最热的地区?

apa*_*gin 6

你猜对了。<type>_disjoint_arraycopy存根是在运行时生成的函数,专门用于加速System.arraycopy调用。

当 JVM 启动时,它会使用当前可用的CPU 功能为某些例程生成优化的机器代码。例如,如果CPU支持AVX2,生成的arraycopy存根将利用AVX2指令

System.arraycopy是HotSpot 内在方法。当由 C2 编译时,调用会System.arraycopy执行必要的检查,然后调用生成的存根例程之一arraycopy

如果StubRoutines::jbyte_disjoint_arraycopy是最热的区域,则基本上意味着您的基准测试将大部分时间花在System.arraycopy处理byte[]数组上。您可以尝试async-profiler来查看它arraycopy是从哪里调用的。