在 JMH 中对 ArrayList.add() 进行基准测试时出现 OutOfMemoryError
OutOfMemoryError when benchmarking ArrayList.add() in JMH
我一直在尝试 运行 基准测试来比较 Java 中 ArrayLists 和 LinkedLists 的 add 方法有多少 ops/ms。我的基准设置如下,但我无法查明是什么导致内存不足错误。可能是设置方法中列表的初始化?
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 5, time = 5)
@Measurement(iterations = 10, time = 5)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ListAddBenchmark {
private int NUMBER = 123;
private List<Integer> arrayList, linkedList;
@Param({"1000","100000","1000000"})
public int iterations;
@Setup(Level.Trial)
public void setup() {
arrayList = new ArrayList<>();
linkedList = new LinkedList<>();
}
@Benchmark
public boolean arrayListBenchmark() {
return arrayList.add(NUMBER);
}
@Benchmark
public boolean linkedListBenchmark() {
return linkedList.add(NUMBER);
}
}
这是我得到的输出...
# JMH version: 1.32
# VM version: JDK 11.0.11, OpenJDK 64-Bit Server VM, 11.0.11+9-Ubuntu-0ubuntu2
# VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# VM options: -Xmx4G -Xms2G
# Blackhole mode: full + dont-inline hint
# Warmup: 5 iterations, 5 s each
# Measurement: 10 iterations, 5 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: dev.example.benchmarks.collections.lists.ListAddBenchmark.arrayListBenchmark
# Parameters: (iterations = 1000)
# Run progress: 0.00% complete, ETA 00:22:30
# Fork: 1 of 3
# Warmup Iteration 1: 22716.118 ops/ms
# Warmup Iteration 2: 16060.593 ops/ms
# Warmup Iteration 3: 16104.508 ops/ms
# Warmup Iteration 4: <failure>
java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOf(Arrays.java:3689)
at java.base/java.util.ArrayList.grow(ArrayList.java:238)
at java.base/java.util.ArrayList.grow(ArrayList.java:243)
at java.base/java.util.ArrayList.add(ArrayList.java:486)
at java.base/java.util.ArrayList.add(ArrayList.java:499)
at dev.example.benchmarks.collections.lists.ListAddBenchmark.arrayListBenchmark(ListAddBenchmark.java:60)
at dev.example.benchmarks.collections.lists.jmh_generated.ListAddBenchmark_arrayListBenchmark_jmhTest.arrayListBenchmark_thrpt_jmhStub(ListAddBenchmark_arrayListBenchmark_jmhTest.java:142)
at dev.example.benchmarks.collections.lists.jmh_generated.ListAddBenchmark_arrayListBenchmark_jmhTest.arrayListBenchmark_Throughput(ListAddBenchmark_arrayListBenchmark_jmhTest.java:83)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:470)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:453)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
有人可以帮助我做错什么吗?
免责声明:这不是问题的答案。但我想与 OP 分享我的发现,这在评论中不太合适。
我在我的系统上遇到了一个不同的异常:
"C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\bin\java.exe" -Xms60G -Dfile.encoding=UTF-8 -classpath C:\Users\vd-wps\git\Schulung\concurrency\target\classes;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-web.5.3\spring-boot-starter-web-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter.5.3\spring-boot-starter-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot.5.3\spring-boot-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-autoconfigure.5.3\spring-boot-autoconfigure-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-logging.5.3\spring-boot-starter-logging-2.5.3.jar;C:\Users\vd-wps\.m2\repository\ch\qos\logback\logback-classic.2.4\logback-classic-1.2.4.jar;C:\Users\vd-wps\.m2\repository\ch\qos\logback\logback-core.2.4\logback-core-1.2.4.jar;C:\Users\vd-wps\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j.14.1\log4j-to-slf4j-2.14.1.jar;C:\Users\vd-wps\.m2\repository\org\apache\logging\log4j\log4j-api.14.1\log4j-api-2.14.1.jar;C:\Users\vd-wps\.m2\repository\org\slf4j\jul-to-slf4j.7.32\jul-to-slf4j-1.7.32.jar;C:\Users\vd-wps\.m2\repository\jakarta\annotation\jakarta.annotation-api.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\vd-wps\.m2\repository\org\yaml\snakeyaml.28\snakeyaml-1.28.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-json.5.3\spring-boot-starter-json-2.5.3.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8.12.4\jackson-datatype-jdk8-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310.12.4\jackson-datatype-jsr310-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names.12.4\jackson-module-parameter-names-2.12.4.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat.5.3\spring-boot-starter-tomcat-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core.0.50\tomcat-embed-core-9.0.50.jar;C:\Users\vd-wps\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el.0.50\tomcat-embed-el-9.0.50.jar;C:\Users\vd-wps\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket.0.50\tomcat-embed-websocket-9.0.50.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-web.3.9\spring-web-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-beans.3.9\spring-beans-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-webmvc.3.9\spring-webmvc-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-aop.3.9\spring-aop-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-context.3.9\spring-context-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-expression.3.9\spring-expression-5.3.9.jar;C:\Users\vd-wps\.m2\repository\io\vavr\vavr[=10=].10.3\vavr-0.10.3.jar;C:\Users\vd-wps\.m2\repository\io\vavr\vavr-match[=10=].10.3\vavr-match-0.10.3.jar;C:\Users\vd-wps\.m2\repository\io\vavr\vavr-jackson[=10=].10.3\vavr-jackson-0.10.3.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\core\jackson-databind.12.4\jackson-databind-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\core\jackson-annotations.12.4\jackson-annotations-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\core\jackson-core.12.4\jackson-core-2.12.4.jar;C:\Users\vd-wps\.m2\repository\org\slf4j\slf4j-api.7.32\slf4j-api-1.7.32.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-core.3.9\spring-core-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-jcl.3.9\spring-jcl-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\openjdk\jmh\jmh-core.33\jmh-core-1.33.jar;C:\Users\vd-wps\.m2\repository\net\sf\jopt-simple\jopt-simple.6\jopt-simple-4.6.jar;C:\Users\vd-wps\.m2\repository\org\apache\commons\commons-math3.2\commons-math3-3.2.jar;C:\Users\vd-wps\.m2\repository\org\openjdk\jmh\jmh-generator-annprocess.33\jmh-generator-annprocess-1.33.jar org.openjdk.jmh.Main live.Foo.*
# JMH version: 1.33
# VM version: JDK 11.0.8, OpenJDK 64-Bit Server VM, 11.0.8+10
# VM invoker: C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\bin\java.exe
# VM options: -Xms60G -Dfile.encoding=UTF-8
# Blackhole mode: full + dont-inline hint (default, use -Djmh.blackhole.autoDetect=true to auto-detect)
# Warmup: 5 iterations, 5 s each
# Measurement: 10 iterations, 5 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: live.Foo.arrayListBenchmark
# Parameters: (iterations = 1000)
# Run progress: 0,00% complete, ETA 00:37:30
# Fork: 1 of 5
# Warmup Iteration 1: 38080,602 ops/ms
# Warmup Iteration 2: 38133,575 ops/ms
# Warmup Iteration 3: 39387,368 ops/ms
# Warmup Iteration 4: 17938,954 ops/ms
# Warmup Iteration 5: 45201,878 ops/ms
Iteration 1: 6122,634 ops/ms
Iteration 2: 97654,786 ops/ms
Iteration 3: <failure>
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at java.base/java.util.Arrays.copyOf(Arrays.java:3689)
at java.base/java.util.ArrayList.grow(ArrayList.java:238)
at java.base/java.util.ArrayList.grow(ArrayList.java:243)
at java.base/java.util.ArrayList.add(ArrayList.java:486)
at java.base/java.util.ArrayList.add(ArrayList.java:499)
at live.Foo.arrayListBenchmark(Foo.java:42)
at live.jmh_generated.Foo_arrayListBenchmark_jmhTest.arrayListBenchmark_thrpt_jmhStub(Foo_arrayListBenchmark_jmhTest.java:142)
at live.jmh_generated.Foo_arrayListBenchmark_jmhTest.arrayListBenchmark_Throughput(Foo_arrayListBenchmark_jmhTest.java:83)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:475)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:458)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
我 运行 几乎所有 RAM(64GB 中的 60)的基准测试。而且TaskManager的负载确实很重
我通过在每次拆解迭代中手动调用 System.gc()
设法抑制了我的 OutOfMemoryError。感谢@majusebetter 帮助确定原因。
我的最终代码现在看起来像:
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ListAddBenchmark {
private int NUMBER = 123;
private List<Integer> arrayList, linkedList;
@Setup(Level.Iteration)
public void setup() {
arrayList = new ArrayList<>();
linkedList = new LinkedList<>();
}
@TearDown(Level.Iteration)
public void teardown() {
System.gc();
}
@Benchmark
public boolean arrayListBenchmark() {
return arrayList.add(NUMBER);
}
@Benchmark
public boolean linkedListBenchmark() {
return linkedList.add(NUMBER);
}
}
最终输出(没有任何内存问题)是:
Benchmark Mode Cnt Score Error Units
ListAddBenchmark.arrayListBenchmark thrpt 30 38587.191 ± 722.036 ops/ms
ListAddBenchmark.linkedListBenchmark thrpt 30 13955.916 ± 574.261 ops/ms
我一直在尝试 运行 基准测试来比较 Java 中 ArrayLists 和 LinkedLists 的 add 方法有多少 ops/ms。我的基准设置如下,但我无法查明是什么导致内存不足错误。可能是设置方法中列表的初始化?
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 5, time = 5)
@Measurement(iterations = 10, time = 5)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ListAddBenchmark {
private int NUMBER = 123;
private List<Integer> arrayList, linkedList;
@Param({"1000","100000","1000000"})
public int iterations;
@Setup(Level.Trial)
public void setup() {
arrayList = new ArrayList<>();
linkedList = new LinkedList<>();
}
@Benchmark
public boolean arrayListBenchmark() {
return arrayList.add(NUMBER);
}
@Benchmark
public boolean linkedListBenchmark() {
return linkedList.add(NUMBER);
}
}
这是我得到的输出...
# JMH version: 1.32
# VM version: JDK 11.0.11, OpenJDK 64-Bit Server VM, 11.0.11+9-Ubuntu-0ubuntu2
# VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# VM options: -Xmx4G -Xms2G
# Blackhole mode: full + dont-inline hint
# Warmup: 5 iterations, 5 s each
# Measurement: 10 iterations, 5 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: dev.example.benchmarks.collections.lists.ListAddBenchmark.arrayListBenchmark
# Parameters: (iterations = 1000)
# Run progress: 0.00% complete, ETA 00:22:30
# Fork: 1 of 3
# Warmup Iteration 1: 22716.118 ops/ms
# Warmup Iteration 2: 16060.593 ops/ms
# Warmup Iteration 3: 16104.508 ops/ms
# Warmup Iteration 4: <failure>
java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOf(Arrays.java:3689)
at java.base/java.util.ArrayList.grow(ArrayList.java:238)
at java.base/java.util.ArrayList.grow(ArrayList.java:243)
at java.base/java.util.ArrayList.add(ArrayList.java:486)
at java.base/java.util.ArrayList.add(ArrayList.java:499)
at dev.example.benchmarks.collections.lists.ListAddBenchmark.arrayListBenchmark(ListAddBenchmark.java:60)
at dev.example.benchmarks.collections.lists.jmh_generated.ListAddBenchmark_arrayListBenchmark_jmhTest.arrayListBenchmark_thrpt_jmhStub(ListAddBenchmark_arrayListBenchmark_jmhTest.java:142)
at dev.example.benchmarks.collections.lists.jmh_generated.ListAddBenchmark_arrayListBenchmark_jmhTest.arrayListBenchmark_Throughput(ListAddBenchmark_arrayListBenchmark_jmhTest.java:83)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:470)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:453)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
有人可以帮助我做错什么吗?
免责声明:这不是问题的答案。但我想与 OP 分享我的发现,这在评论中不太合适。
我在我的系统上遇到了一个不同的异常:
"C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\bin\java.exe" -Xms60G -Dfile.encoding=UTF-8 -classpath C:\Users\vd-wps\git\Schulung\concurrency\target\classes;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-web.5.3\spring-boot-starter-web-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter.5.3\spring-boot-starter-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot.5.3\spring-boot-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-autoconfigure.5.3\spring-boot-autoconfigure-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-logging.5.3\spring-boot-starter-logging-2.5.3.jar;C:\Users\vd-wps\.m2\repository\ch\qos\logback\logback-classic.2.4\logback-classic-1.2.4.jar;C:\Users\vd-wps\.m2\repository\ch\qos\logback\logback-core.2.4\logback-core-1.2.4.jar;C:\Users\vd-wps\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j.14.1\log4j-to-slf4j-2.14.1.jar;C:\Users\vd-wps\.m2\repository\org\apache\logging\log4j\log4j-api.14.1\log4j-api-2.14.1.jar;C:\Users\vd-wps\.m2\repository\org\slf4j\jul-to-slf4j.7.32\jul-to-slf4j-1.7.32.jar;C:\Users\vd-wps\.m2\repository\jakarta\annotation\jakarta.annotation-api.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\vd-wps\.m2\repository\org\yaml\snakeyaml.28\snakeyaml-1.28.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-json.5.3\spring-boot-starter-json-2.5.3.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8.12.4\jackson-datatype-jdk8-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310.12.4\jackson-datatype-jsr310-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names.12.4\jackson-module-parameter-names-2.12.4.jar;C:\Users\vd-wps\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat.5.3\spring-boot-starter-tomcat-2.5.3.jar;C:\Users\vd-wps\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core.0.50\tomcat-embed-core-9.0.50.jar;C:\Users\vd-wps\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el.0.50\tomcat-embed-el-9.0.50.jar;C:\Users\vd-wps\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket.0.50\tomcat-embed-websocket-9.0.50.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-web.3.9\spring-web-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-beans.3.9\spring-beans-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-webmvc.3.9\spring-webmvc-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-aop.3.9\spring-aop-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-context.3.9\spring-context-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-expression.3.9\spring-expression-5.3.9.jar;C:\Users\vd-wps\.m2\repository\io\vavr\vavr[=10=].10.3\vavr-0.10.3.jar;C:\Users\vd-wps\.m2\repository\io\vavr\vavr-match[=10=].10.3\vavr-match-0.10.3.jar;C:\Users\vd-wps\.m2\repository\io\vavr\vavr-jackson[=10=].10.3\vavr-jackson-0.10.3.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\core\jackson-databind.12.4\jackson-databind-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\core\jackson-annotations.12.4\jackson-annotations-2.12.4.jar;C:\Users\vd-wps\.m2\repository\com\fasterxml\jackson\core\jackson-core.12.4\jackson-core-2.12.4.jar;C:\Users\vd-wps\.m2\repository\org\slf4j\slf4j-api.7.32\slf4j-api-1.7.32.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-core.3.9\spring-core-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\springframework\spring-jcl.3.9\spring-jcl-5.3.9.jar;C:\Users\vd-wps\.m2\repository\org\openjdk\jmh\jmh-core.33\jmh-core-1.33.jar;C:\Users\vd-wps\.m2\repository\net\sf\jopt-simple\jopt-simple.6\jopt-simple-4.6.jar;C:\Users\vd-wps\.m2\repository\org\apache\commons\commons-math3.2\commons-math3-3.2.jar;C:\Users\vd-wps\.m2\repository\org\openjdk\jmh\jmh-generator-annprocess.33\jmh-generator-annprocess-1.33.jar org.openjdk.jmh.Main live.Foo.*
# JMH version: 1.33
# VM version: JDK 11.0.8, OpenJDK 64-Bit Server VM, 11.0.8+10
# VM invoker: C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\bin\java.exe
# VM options: -Xms60G -Dfile.encoding=UTF-8
# Blackhole mode: full + dont-inline hint (default, use -Djmh.blackhole.autoDetect=true to auto-detect)
# Warmup: 5 iterations, 5 s each
# Measurement: 10 iterations, 5 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: live.Foo.arrayListBenchmark
# Parameters: (iterations = 1000)
# Run progress: 0,00% complete, ETA 00:37:30
# Fork: 1 of 5
# Warmup Iteration 1: 38080,602 ops/ms
# Warmup Iteration 2: 38133,575 ops/ms
# Warmup Iteration 3: 39387,368 ops/ms
# Warmup Iteration 4: 17938,954 ops/ms
# Warmup Iteration 5: 45201,878 ops/ms
Iteration 1: 6122,634 ops/ms
Iteration 2: 97654,786 ops/ms
Iteration 3: <failure>
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at java.base/java.util.Arrays.copyOf(Arrays.java:3689)
at java.base/java.util.ArrayList.grow(ArrayList.java:238)
at java.base/java.util.ArrayList.grow(ArrayList.java:243)
at java.base/java.util.ArrayList.add(ArrayList.java:486)
at java.base/java.util.ArrayList.add(ArrayList.java:499)
at live.Foo.arrayListBenchmark(Foo.java:42)
at live.jmh_generated.Foo_arrayListBenchmark_jmhTest.arrayListBenchmark_thrpt_jmhStub(Foo_arrayListBenchmark_jmhTest.java:142)
at live.jmh_generated.Foo_arrayListBenchmark_jmhTest.arrayListBenchmark_Throughput(Foo_arrayListBenchmark_jmhTest.java:83)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:475)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:458)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
我 运行 几乎所有 RAM(64GB 中的 60)的基准测试。而且TaskManager的负载确实很重
我通过在每次拆解迭代中手动调用 System.gc()
设法抑制了我的 OutOfMemoryError。感谢@majusebetter 帮助确定原因。
我的最终代码现在看起来像:
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ListAddBenchmark {
private int NUMBER = 123;
private List<Integer> arrayList, linkedList;
@Setup(Level.Iteration)
public void setup() {
arrayList = new ArrayList<>();
linkedList = new LinkedList<>();
}
@TearDown(Level.Iteration)
public void teardown() {
System.gc();
}
@Benchmark
public boolean arrayListBenchmark() {
return arrayList.add(NUMBER);
}
@Benchmark
public boolean linkedListBenchmark() {
return linkedList.add(NUMBER);
}
}
最终输出(没有任何内存问题)是:
Benchmark Mode Cnt Score Error Units
ListAddBenchmark.arrayListBenchmark thrpt 30 38587.191 ± 722.036 ops/ms
ListAddBenchmark.linkedListBenchmark thrpt 30 13955.916 ± 574.261 ops/ms