垃圾回收器(.net/java)是实时系统的问题吗?

当构建一个需要非常一致和快速响应的系统时,垃圾回收器是一个潜在的问题吗?

我记得几年前的恐怖故事,典型的例子总是一个动作游戏,你的角色会在中途停止几秒钟,当垃圾收集器进行清理时。

我们又过了几年,但我想知道这是否仍然是一个问题。我读过.Net 4中新的垃圾收集器,但它看起来很像一个大黑匣子,你只需要相信一切都会好起来的。

如果你有一个系统总是必须快速响应,有一个垃圾回收器是一个太大的问题,选择一个更硬核更好,像c ++这样的语言自己控制它吗?我讨厌如果它被证明是一个问题,除了等待新版本的运行时或做非常奇怪的事情来尝试和影响收集器之外,你基本上无能为力。

编辑

感谢所有伟大的资源。但是,似乎大多数文章/自定义gc/解决方案都与Java环境有关。.Net 是否还具有自定义 GC 的调优功能或选项?


答案 1

确切地说,垃圾回收器是实时系统的一个问题。更准确地说,可以用具有自动内存管理的语言编写实时软件。

有关使用 Java 实现实时行为的方法之一的 Java 实时规范,可以找到更多详细信息。RTSJ背后的想法非常简单 - 不要使用堆。RTSJ 提供了新品种的 Runnable 对象,以确保线程不会访问任何类型的堆内存。线程可以访问作用域内存(此处没有什么异常;值在作用域关闭时被销毁)或不朽内存(在整个应用程序生存期内都存在)。不朽记忆中的变量一次又一次地用新值被覆盖。

通过使用不朽内存,RTSJ确保线程不会访问堆,更重要的是,系统没有垃圾回收器来抢占线程执行程序。

更多细节可以在JPL和Sun发表的论文“Project Golden Gate: Towards Real-Time Java in Space Mission”中找到


答案 2

我用Java和.NET编写过游戏,但从未发现这是一个大问题。我希望你的“恐怖故事”是基于多年前的垃圾收集器 - 从那时起,这项技术确实已经走了很长一段路。

在垃圾回收的基础上,我唯一会犹豫是否要使用Java/ .NET的是带有硬实时约束的嵌入式编程(例如运动控制器)。

但是,您确实需要注意GC暂停,以下所有功能都有助于最大限度地降低GC暂停的风险:

  • 最大限度地减少新的对象分配 - 虽然在现代GC系统中,对象分配非常快,但它们确实有助于将来的暂停,因此应该尽量减少。您可以使用预分配对象数组、保留对象池或使用未装箱的基元等技术。
  • 对大量使用的函数和数据类型使用专门的低延迟库(如 Javalution)。这些是专门为实时/低延迟应用而设计的
  • 确保在有多个版本可用时使用最佳 GC 算法。我听说过 Sun G1 收集器在低延迟应用中的好话。最好的GC系统同时进行大部分收集,因此垃圾收集不必长时间“停止世界” (
  • 适当地调整 GC 参数。通常在整体性能和暂停时间之间需要权衡,您可能希望以牺牲前者为代价来改进后者。

如果你非常富有,你当然可以购买支持硬件GC的机器。:-)