有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带有JMH和模式的java OutOfMemory。平均时间

我正在编写一个微基准测试来比较使用+操作符与StringBuilder的字符串连接。为此,我基于OpenJDK example that uses the batchSize parameter创建了一个JMH基准类:

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@Measurement(batchSize = 10000, iterations = 10)
@Warmup(batchSize = 10000, iterations = 10)
@Fork(1)
public class StringConcatenationBenchmark {

    private String string;

    private StringBuilder stringBuilder;

    @Setup(Level.Iteration)
    public void setup() {
        string = "";
        stringBuilder = new StringBuilder();
    }

    @Benchmark
    public void stringConcatenation() {
        string += "some more data";
    }

    @Benchmark
    public void stringBuilderConcatenation() {
        stringBuilder.append("some more data");
    }

}

当我运行基准测试时,我得到了stringBuilderConcatenation方法的以下错误:

java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3332)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:421)
    at java.lang.StringBuilder.append(StringBuilder.java:136)
    at link.pellegrino.string_concatenation.StringConcatenationBenchmark.stringBuilderConcatenation(StringConcatenationBenchmark.java:29)
    at link.pellegrino.string_concatenation.generated.StringConcatenationBenchmark_stringBuilderConcatenation.stringBuilderConcatenation_avgt_jmhStub(StringConcatenationBenchmark_stringBuilderConcatenation.java:165)
    at link.pellegrino.string_concatenation.generated.StringConcatenationBenchmark_stringBuilderConcatenation.stringBuilderConcatenation_AverageTime(StringConcatenationBenchmark_stringBuilderConcatenation.java:130)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:430)
    at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:412)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我认为默认的JVM堆大小必须增加,所以我尝试使用JMH提供的-Xmx10G值和-jvmArgs选项来允许高达10GB的内存。不幸的是,我仍然得到了错误

因此,我试图将batchSize参数的值降低到1,但仍然得到OutOfMemoryError

我找到的唯一解决方法是将基准模式设置为Mode.SingleShotTime。因为这个模式似乎考虑了一个批处理(即使在单元列中显示了 S/OP> EEM>),所以我得到了我想要的度量:执行批处理操作的平均时间。然而,我仍然不明白为什么它不能与Mode.AverageTime一起工作

还请注意,无论使用何种基准模式,方法stringConcatenation的基准都能按预期工作。只有使用StringBuilder的stringBuilderConcatenation方法才会出现此问题

欢迎提供任何帮助,以了解为什么前面的示例不使用设置为Mode.AverageTime的基准模式

我使用的JMH版本是1.10.4


共 (0) 个答案