为什么Java / Linux堆栈无法“实时”运行的原因是什么?


20

我经常听到开发人员提的是Java的不能“ 实时 ”,这意味着在Linux上运行的Java应用程序不能满足一个确定性的实时系统的要求,如对RIOT-OS等运行的东西

我试图理解为什么。我的SWAG告诉我,这可能主要是由于Java的Garbage Collector可以在任何时间运行并完全暂停系统。而且,尽管那里有所谓的“无暂停GC”,但我不一定相信他们的广告,也没有每个JVM实例$ 80K的兴趣来支持这个业余项目!

我还阅读了有关在Linux上运行无人机软件的文章。在那篇文章中,作者描述了Linux几乎导致无人机撞车的情况:

在选择在Pi上执行低级控制循环(PID)之后,我学到了很难的一课-为了变得聪明,我决定在循环的中间放置一个日志记录以进行调试-Quad最初运行良好,但随后Linux决定花2秒写一个日志条目,然后四边形几乎撞到了我的车上!

现在,尽管那个作者用C ++编写了无人机软件,但我可以想象,在Linux上运行的Java应用程序可能遭受同样的命运。

根据维基百科:

如果一个操作的总正确性不仅取决于它的逻辑正确性,还取决于它执行的时间,那么该系统就是实时的。

所以对我来说,这意味着“ 如果完全正确需要逻辑上的正确性和及时性,那么您就不会实时。

假设我已经编写了一个Java应用程序以使其具有超强的性能,可以这么说,我已经“挤满了柠檬”,并且不能合理地用Java编写该程序以使其更快。

总而言之,我的问题是:我正在寻找可以向我解释所有/大多数运行Linux的Java应用程序无法成为“实时应用程序”的原因。意思是,什么使Java / Linux堆栈上的所有事物类别阻止了它“及时”,从而使其“ 完全正确 ”?如前所述,GC和Linux日志刷新似乎可以暂停执行,但是我敢肯定Java应用程序本身之外还有更多事情会导致计时/性能下降,并使其难以满足最终期限的要求。这些是什么?


3
参见JSR001
coredump

1
FWIW,可以使Linux在硬实时系统中以适当的方式运行,但是它确实包含了一些典型的嵌入式爱好者可能会忽略的技术。有很多关于Linux实时开发的好书。我建议购买一个。
Jules

@coredump不幸的是,据我在jsr-1实现列表中所见,只有四种实现,其中两种目前尚不可用,另外两种似乎是相当昂贵的商业产品,可能已经淘汰了询问者的价格范围。
Jules

Answers:


28

软件不是实时的,不是尽可能快的,而是保证过程在某个确定的时间段内完成。在软实时系统中,保证是好的,但并非绝对必要。例如,在游戏中,一帧所需的计算应在一个帧的时间内完成,否则帧速率将下降。这会降低游戏质量,但不会使其不正确。例如,即使游戏偶尔停顿,《我的世界》还是很有趣的。

在硬实时系统中,我们没有这种自由。飞行控制软件必须在一定期限内做出反应,否则车辆可能会坠毁。而且硬件,操作系统和软件必须协同工作以支持实时。

例如,操作系统具有调度程序来决定何时运行哪个线程。对于实时程序,调度程序必须保证足够大,足够频繁的时隙。要在这样的插槽中执行的任何其他进程都必须中断,以支持实时进程。这需要具有显式实时支持的调度程序。

同样,一个用户空间程序将对内核进行系统调用。在实时操作系统中,这些也必须是实时的。例如,必须保证写入文件句柄的时间不超过x个时间单位,这将解决日志问题。这影响了如何实现这样的系统调用,例如,如何使用缓冲区。这也意味着如果调用无法在要求的时间内完成,则调用必须失败,并且用户空间程序必须准备好应对这些情况。对于Java,JVM和标准库也类似于内核,因此需要显式的实时支持。

对于任何实时的内容,您的编程风格都会改变。如果您没有无休止的时间,则必须将自己限制在小问题上。您的所有循环都必须以某个常量为边界。因为您有大小上限,所以可以静态分配所有内存。禁止无限制地递归。这违背了许多最佳实践,但是它们不适用于实时系统。例如,日志系统在写入日志消息时可能会使用静态分配的环形缓冲区来存储日志消息。一旦开始,旧日志将被丢弃,否则此情况可能是错误。


4

来自维基百科

RTOS的一个关键特性是其一致性程度,该一致性涉及接受和完成应用程序任务所花费的时间;变化是抖动。

重要的是要对抖动进行量化,以便将系统视为实时的。文章继续说,如果抖动通常是有界的,则系统是实时的。如果抖动总是有界的,那么系统就很难实时进行

除非您使用的Java和Linux版本是根据抖动量化的,否则它们不是实时的。垃圾收集和日志写入肯定是抖动的来源,但是,如果将网络抖动引入到您的进程中,则即使是自动处理(例如)网络数据包也很重要。


1

首先,香草Linux本身无法实时进行。这就是开发RTLinux的原因。

可以说,您在RTLinux上运行了几个Java进程,因为所有这些进程都是由内核调度的,所以它们仍被视为实时进程,即,如果一个进程晚了,其他进程仍然可以保证其CPU时间。

现在,如果Java进程运行Green线程,则由于JVM不进行实时调度,因此这些线程的执行将不再是实时的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.