简体   繁体   English

Raspberry Pi上Java的线程性能问题

[英]Thread performance issues for Java on Raspberry Pi

The goal of this application is to handle 800 simultaneous clients over TCP, each of them sends a 3.5kb xml every second. 该应用程序的目标是通过TCP处理800个并发客户端,每个客户端每秒发送一个3.5kb xml。 Each of these requests needs to be parsed (see code snipped). 需要解析这些请求中的每一个(请参阅代码剪切)。 This happens on different threads. 这发生在不同的线程上。

The limitation of this project is that it has to run on a small Raspberry Pi3 (1.2 ghz quad core, 1gb ram). 这个项目的局限在于它必须在一个小的Raspberry Pi3(1.2 ghz四核,1gb ram)上运行。 And i run into utilization issues when i increase the load above 150 simultaneous clients (80% cpu usage). 当我将负载增加到150个以上的客户端(80%的CPU使用率)时,我遇到了利用率问题。

When i run this program my development machine it seems to run very well. 当我运行这个程序我的开发机器似乎运行得很好。 (0-1% usage, under 150). (0-1%用量,150以下)。 I understand that my development machine is more powerful than the RPI, and therefore runs better. 我知道我的开发机器比RPI更强大,因此运行得更好。 But the difference seems to be too big. 但差异似乎太大了。

In my current setup i use Java nio to handle/read all the incoming connections. 在我目前的设置中,我使用Java nio来处理/读取所有传入的连接。 Then i use multiple threads to read the data. 然后我使用多个线程来读取数据。

当前设置

This is the simple code that currently runs on the processing thread. 这是当前在处理线程上运行的简单代码。 Also tried reading a simple byte[] array 1 byte at a time. 还尝试一次读取一个简单的byte []数组1个字节。 And even reading a StaX stream. 甚至阅读StaX流。 Every variation of reading that i tried, the 'read type' of operation gives gives the worst performance. 我尝试过的读数的每个变化,操作的“读取类型”给出了最差的性能。

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;
}

According to my profiler the Input.read() call uses a huge amount of processing power on the Pi and accounts for 97% of the total cpu time. 根据我的分析器,Input.read()调用在Pi上使用了大量的处理能力,占总CPU时间的97%。 the other 3% is the Main thread that handles the connections. 另外3%是处理连接的主线程。

On my development machine this is almost flipped and the Main thread accounts for most of the cpu usage, 93%. 在我的开发机器上,这几乎被翻转,主线程占了大部分CPU使用率的93%。 And 7% goes to the processing threads. 7%用于处理线程。

What could cause this big difference? 什么可能导致这个巨大的差异? why is this read() call on the pi so expensive compared to my other machine, could it have something to do with memory? 与我的其他机器相比,为什么pi上的read()调用如此昂贵,它可能与内存有关吗?

Notes: 笔记:

  • Pi runs raspbian linux - openjdk 1.8.0_40-internal Pi运行raspbian linux - openjdk 1.8.0_40-internal
  • Dev machine runs win 10 - Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Dev机器运行win 10 - Java(TM)SE运行时环境(版本1.8.0_121-b13)
  • Tried running with -Xms -Xmx flag on both machines, same result. 尝试在两台机器上运行-Xms -Xmx标志,结果相同。

Turns out that the problem was a combination of both JVM and 32bits OS on the Raspberry Pi 3. When running 32bit raspbian with OpenJDK my application had very poor performance (Especially on the 'read' calls). 事实证明,问题是Raspberry Pi 3上的JVM和32位操作系统的组合。当使用OpenJDK运行32位raspbian时,我的应用程序的性能非常差(特别是在“读取”调用上)。 Switching to the Oracle JVM gave me the 'better' expected performance. 切换到Oracle JVM给了我“更好”的预期性能。

However when switching to a 64bit OS (OpensSuse in my case) the performance was good with both the OpenJDK and Oracle JVM. 但是当切换到64位操作系统(在我的情况下是OpensSuse)时,OpenJDK和Oracle JVM的性能都很好。

(Credits to @jww in the comments, for suggesting to switch to a 64 bit OS) (在评论中致@jww,建议切换到64位操作系统)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM