Sai*_*mad 5 java performance benchmarking multithreading jvm
我正在对从Object将具有的数据类型转换的总延迟进行基准测试。但是我遇到了一个非常奇怪的 Java 集合行为,在这种情况下,一个List.
List<Long> data = new ArrayList<>();
int SIZE = 50_000_000;
long currentTime = System.currentTimeMillis();
for (int i = 0; i < SIZE; i++) {
data.add(currentTime++);
}
Run Code Online (Sandbox Code Playgroud)
在我的Intel i5 8250u(4 核)上运行上述代码时,CPU 利用率在 IntelliJ Idea 上为 100%。所以我认为这可能是因为 IntelliJ,因此我将代码移动到具有 20 个内核的 Azure VM(运行 CentOS 7.4),令我惊讶的是,这段代码最终消耗了1500% 的CPU(来自top命令的结果),即 15 个内核。
我无法理解的是:单线程 Java 程序代码如何消耗 1 个以上的内核?
编辑:
重现步骤:
运行上面的代码。
机器配置:
笔记本电脑:4 核 16Gb RAM,Oracle Java 1.8_161
Azure VM:20 核 148GB RAM,Oracle Java 1.8_161
笔记本电脑上 JVisualVM 的输出:
您的测试只会分配内存。所以它很快耗尽了初始堆内存,导致 Full GC 运行。然后堆增加,但它又很快被填满,导致另一个 Full GC,等等。
$ java -XX:+PrintGC Test
[GC (Allocation Failure) 27648K->20757K(104448K), 0.0296779 secs]
[GC (Allocation Failure) 48405K->40538K(132096K), 0.0293287 secs]
[GC (Allocation Failure) 83084K->82453K(138752K), 0.0615143 secs]
[Full GC (Ergonomics) 82453K->75113K(225792K), 0.5392036 secs]
[GC (Allocation Failure) 124981K->139346K(254464K), 0.0563272 secs]
[Full GC (Ergonomics) 139346K->112504K(353792K), 0.5240216 secs]
[GC (Allocation Failure) 185709K->208841K(380416K), 0.0864858 secs]
[Full GC (Ergonomics) 208841K->168513K(512512K), 0.9035611 secs]
...
Run Code Online (Sandbox Code Playgroud)
因此,您观察到的是一系列长的 Full GC 周期。JDK 8 中默认的垃圾收集器是 Parallel,并行 GC 线程的数量等于 CPU 的数量。
如果您以线程模式 ( )运行async-profiler-t,您会发现几乎所有 CPU 时间都用于在多个线程中运行垃圾收集。
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |