性能问答>为什么运行单线程 Java 程序会导致许多内核处于活动状态?>
1回复

为什么运行单线程 Java 程序会导致许多内核处于活动状态?



我在对从 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++);
}

我在我的 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 的输出
WUdax.png

A01la.png

670 阅读
请先登录,再评论

你的测试只分配内存,别的什么都不做, 所以很快就耗尽了初始堆内存,导致 Full GC 运行。 然后堆增加,但它又很快被填满,导致另一个 Full GC。
所以你观察到的是一系列长的 Full GC 周期。 JDK 8 中默认的垃圾收集器是 Parallel,并行 GC 线程的数量等于 CPU 的数量。
如果你以线程模式 (-t) 运行 async-profiler,你会发现几乎所有 CPU 时间都用于在多个线程中做垃圾收集。

7月前