Raspberry Pi 上 Java 的线程性能问题
Thread performance issues for Java on Raspberry Pi
此应用程序的目标是通过 TCP 处理 800 个并发客户端,每个客户端每秒发送 3.5kb xml。这些请求中的每一个都需要被解析(参见代码片段)。这发生在不同的线程上。
该项目的局限性在于它必须 运行 在小型 Raspberry Pi3(1.2 ghz 四核,1gb 内存)上运行。当我将负载增加到超过 150 个并发客户端(80% cpu 使用率)时,我 运行 陷入了利用率问题。
当我 运行 这个程序在我的开发机器上似乎 运行 很好。 (0-1% 使用率,低于 150)。我知道我的开发机器比 RPI 更强大,因此 运行s 更好。不过好像差距太大了。
在我当前的设置中,我使用 Java nio 来 handle/read 所有传入连接。然后我使用多线程读取数据。
这是当前 运行 在处理线程上的简单代码。还尝试一次读取一个简单的 byte[] 数组 1 个字节。甚至阅读 StaX 流。
我尝试过的每一种阅读变化,'read type' 操作给出了最差的性能。
BufferedInputStream input = new BufferedInputStream(new ByteArrayInputStream(buffer.array(), 0, bytecount));
int current;
/* In this snippet input.read() is the cause of performance issues
Reading directly from byte[] gives similar poor performance.
*/
while ((current = input.read()) != -1) {
continue;
}
根据我的分析器,Input.read() 调用在 Pi 上使用了大量的处理能力,占总 cpu 时间的 97%。另外 3% 是处理连接的主线程。
在我的开发机器上,这几乎是颠倒的,主线程占了大部分 cpu 使用,93%。 7% 用于处理线程。
是什么导致了如此大的差异?与我的其他机器相比,为什么 pi 上的这个 read() 调用如此昂贵,这可能与内存有关吗?
备注:
- Pi 运行s raspbian linux - openjdk 1.8.0_40-internal
- Dev machine 运行s win 10 - Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
- 在两台机器上尝试了 运行 -Xms -Xmx 标志,结果相同。
原来问题是 Raspberry Pi 上的 JVM 和 32 位 OS 的组合 3. 当 运行 32 位 raspbian 与 OpenJDK 我的应用程序有非常性能不佳(尤其是在 'read' 调用上)。切换到 Oracle JVM 后,我获得了 'better' 预期的性能。
然而,当切换到 64 位 OS(在我的例子中是 OpensSuse)时,OpenJDK 和 Oracle JVM 的性能都很好。
(在评论中感谢@jww,建议切换到 64 位 OS)
此应用程序的目标是通过 TCP 处理 800 个并发客户端,每个客户端每秒发送 3.5kb xml。这些请求中的每一个都需要被解析(参见代码片段)。这发生在不同的线程上。
该项目的局限性在于它必须 运行 在小型 Raspberry Pi3(1.2 ghz 四核,1gb 内存)上运行。当我将负载增加到超过 150 个并发客户端(80% cpu 使用率)时,我 运行 陷入了利用率问题。
当我 运行 这个程序在我的开发机器上似乎 运行 很好。 (0-1% 使用率,低于 150)。我知道我的开发机器比 RPI 更强大,因此 运行s 更好。不过好像差距太大了。
在我当前的设置中,我使用 Java nio 来 handle/read 所有传入连接。然后我使用多线程读取数据。
这是当前 运行 在处理线程上的简单代码。还尝试一次读取一个简单的 byte[] 数组 1 个字节。甚至阅读 StaX 流。 我尝试过的每一种阅读变化,'read type' 操作给出了最差的性能。
BufferedInputStream input = new BufferedInputStream(new ByteArrayInputStream(buffer.array(), 0, bytecount));
int current;
/* In this snippet input.read() is the cause of performance issues
Reading directly from byte[] gives similar poor performance.
*/
while ((current = input.read()) != -1) {
continue;
}
根据我的分析器,Input.read() 调用在 Pi 上使用了大量的处理能力,占总 cpu 时间的 97%。另外 3% 是处理连接的主线程。
在我的开发机器上,这几乎是颠倒的,主线程占了大部分 cpu 使用,93%。 7% 用于处理线程。
是什么导致了如此大的差异?与我的其他机器相比,为什么 pi 上的这个 read() 调用如此昂贵,这可能与内存有关吗?
备注:
- Pi 运行s raspbian linux - openjdk 1.8.0_40-internal
- Dev machine 运行s win 10 - Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
- 在两台机器上尝试了 运行 -Xms -Xmx 标志,结果相同。
原来问题是 Raspberry Pi 上的 JVM 和 32 位 OS 的组合 3. 当 运行 32 位 raspbian 与 OpenJDK 我的应用程序有非常性能不佳(尤其是在 'read' 调用上)。切换到 Oracle JVM 后,我获得了 'better' 预期的性能。
然而,当切换到 64 位 OS(在我的例子中是 OpensSuse)时,OpenJDK 和 Oracle JVM 的性能都很好。
(在评论中感谢@jww,建议切换到 64 位 OS)