首页 > 解决方案 > 卡尺为所有分配指标给出 0

问题描述

Caliper中的以下基准测试代码

import com.google.caliper.BeforeExperiment;
import com.google.caliper.Benchmark;
import com.google.caliper.Param;
import com.google.caliper.runner.CaliperMain;

public class Bench_IsInstrumentationWorking {
    
    @Param({"1000"})
    private int size;

    private double[] array;
    
    @BeforeExperiment
    private void init(){
        array=new double[size];
    }

    @Benchmark
    public void bench(int reps){
        for (int i = 0; i < reps; i++) {
            for (int j = 0; j < size; j++) {
                array[j]=Math.random();
            }
        }
    }
    public static void main(String[] args) {
        CaliperMain.main(Bench_IsInstrumentationWorking.class,args);
    }

}

所有分配指标的结果为 0:

Experiment selection: 
  Benchmark Methods:   [bench]
  Instruments:   [allocation, runtime]
  User parameters:   {size=[1000]}
  Target VMs:  [default@local]

This selection yields 2 experiments.
Trial Report (1 of 2):
  Experiment {instrument=allocation, benchmarkMethod=bench, target=default@local, parameters={size=1000}}
  Results:
    bytes(B): min=0.00, 1st qu.=0.00, median=0.00, mean=0.00, 3rd qu.=0.00, max=0.00
    objects: min=0.00, 1st qu.=0.00, median=0.00, mean=0.00, 3rd qu.=0.00, max=0.00
Trial Report (2 of 2):
  Experiment {instrument=runtime, benchmarkMethod=bench, target=default@local, parameters={size=1000}}
  Results:
    runtime(ns): min=17175.93, 1st qu.=17264.70, median=17345.48, mean=17403.70, 3rd qu.=17414.21, max=18080.08
Collected 27 measurements from:
  2 instrument(s)
  2 virtual machine(s)
  1 benchmark(s)

Execution complete: 19.28 s.

~/tmp/someNumber/trial-1.log充满了

Oct 05, 2021 5:53:26 AM com.google.monitoring.runtime.instrumentation.AllocationInstrumenter instrument
[stderr] WARNING: Failed to instrument class.
[stderr] java.lang.IllegalArgumentException: Unsupported class file major version 60
[stderr]    at com.google.monitoring.runtime.instrumentation.asm.ClassReader.<init>(ClassReader.java:195)
[stderr]    at com.google.monitoring.runtime.instrumentation.asm.ClassReader.<init>(ClassReader.java:176)
[stderr]    at com.google.monitoring.runtime.instrumentation.asm.ClassReader.<init>(ClassReader.java:162)
[stderr]    at com.google.monitoring.runtime.instrumentation.AllocationInstrumenter.instrument(AllocationInstrumenter.java:192)
[stderr]    at com.google.monitoring.runtime.instrumentation.AllocationInstrumenter.instrument(AllocationInstrumenter.java:220)
[stderr]    at com.google.monitoring.runtime.instrumentation.AllocationInstrumenter.transform(AllocationInstrumenter.java:174)
[stderr]    at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:244)
[stderr]    at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
[stderr]    at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:565)
[stderr]    at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
[stderr]    at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:168)
[stderr]    at com.google.monitoring.runtime.instrumentation.AllocationInstrumenter.bootstrap(AllocationInstrumenter.java:157)
[stderr]    at com.google.monitoring.runtime.instrumentation.AllocationInstrumenter.premain(AllocationInstrumenter.java:109)
[stderr]    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[stderr]    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
[stderr]    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[stderr]    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
[stderr]    at com.google.monitoring.runtime.instrumentation.AllocationInstrumenterBootstrap.premain(AllocationInstrumenterBootstrap.java:48)
[stderr]    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[stderr]    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
[stderr]    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[stderr]    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
[stderr]    at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:515)
[stderr] 
  1. 为什么会这样以及如何解决这个问题?

我的猜测是 Caliper 使用的库可能不适合 JDK 16(请参阅下面的环境详细信息)。如果是这样,当前的最大值是多少。它将运行的受支持版本?

进一步调查显示,即使在 JDK x.0.2 (11<=x<=14) 上运行,分配也保持为 0,但日志文件没有显示错误。在 15.0.2 上,行为与 16 和 17 相同(如上)


环境:
卡尺:1.0-beta-3
Gradle:7.2
OpenJDK:16.0.1
IDE:IntelliJ 2021.2.2,社区版
操作系统:Ubuntu 20.04.3 LTS

构建.gradle:

plugins {
    id 'java'
}

group 'yourGroup.id'
version '0.0-SNAPSHOT'

repositories {
    mavenCentral()
//    mavenLocal()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation 'com.google.caliper:caliper:1.0-beta-3'
}

test {
    useJUnitPlatform()
}

标签: javagradlebenchmarkingcaliper

解决方案


Google 分配不支持 Java 16 或 17,因为其中包含不支持这些的 ASM 的阴影副本。

它需要使用 ASM 8 或 9 重建 Google 分配


推荐阅读