gpt4 book ai didi

java - 为什么 .toString() 似乎修复了 StringBuilder 的 OutOfMemoryError 异常?

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:01:18 25 4
gpt4 key购买 nike

我正在学习如何使用 JMH 进行微基准测试。我从看似简单的事情开始:StringBuilderString += 的字符串连接。

根据我的理解,我应该制作一个包含 StringBuilder 实例的 State 对象,因为我不想对其构造函数进行基准测试(我也不想反正每次迭代都清空一个)。 String += 测试也是如此 - 我希望将 State 中的 String 对象与新字符串连接起来。

这是我的代码:

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class Test {

@State(Scope.Thread)
public static class BenchmarkState {

public StringBuilder builder;
public String regularString;

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

}

@Benchmark
public String stringTest(BenchmarkState state) {
state.regularString += "hello";
return state.regularString;
}

@Benchmark
public String stringBuilderTest(BenchmarkState state) {
state.builder.append("hello");
return state.builder.toString();
}

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(Test.class.getSimpleName())
.forks(1)
.timeUnit(TimeUnit.MILLISECONDS)
.mode(Mode.Throughput)
.measurementTime(TimeValue.seconds(10))
.build();

new Runner(opt).run();
}

}

它有效,但我在想 - 我不想在每次迭代结束时调用 .toString()。我只测试串联。所以我决定通过返回 null 来删除它。

但是,这发生在第一次预热迭代期间:

java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
at java.lang.StringBuilder.append(StringBuilder.java:136)

我知道如果 JMH 尽可能快地附加到 StringBuilder,我会很快耗尽内存,所以我对 OutOfMemoryError 问题并不感到惊讶.但我不明白为什么 builder.toString() 会修复它。

所以我的问题是:

  • 为什么 builder.toString() 避免了 OutOfMemoryError 问题?无论如何,StringBuilder 不会仍然将所有字符保留在内存中吗?

  • 假设我不希望 StringBuilder 的构造函数及其 .toString() 方法成为基准测试的一部分,我该如何正确编写这个测试?

最佳答案

调用 toString() 需要时间,并且会产生垃圾,需要 GC 运行,进一步降低代码速度。

由于测试有时间限制,这些减速可能会导致测试在消耗所有内存之前停止。如果增加时间限制,即使使用 toString,代码也可能会因 OOM 而失败,只会花费更长的时间。

关于java - 为什么 .toString() 似乎修复了 StringBuilder 的 OutOfMemoryError 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51227953/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com