【问题标题】:Garbage Collector in Real-Time System实时系统中的垃圾收集器
【发布时间】:2009-11-04 18:50:23
【问题描述】:

我是 C#/Java 新手,并计划将其原型用于软实时系统。

如果我像在 C++ 中的内存管理那样编写 C#/Java 应用程序,即明确“删除”不再使用的对象,那么应用程序是否仍会受到垃圾收集器的影响?如果是这样,它对我的​​应用有何影响?

对不起,如果这听起来像是一个显而易见的答案,但作为新人,我想彻底。

【问题讨论】:

  • 那为什么不直接使用 C++ 或 C 呢?实时编程已经够难了,你不想同时与虚拟机作斗争。

标签: garbage-collection real-time soft-real-time


【解决方案1】:

看看IBM's Metronome,他们用于实时系统的垃圾收集器。

【讨论】:

【解决方案2】:

您的前提是错误的:您不能在 Java 或 C# 中显式“删除”对象,因此您的应用程序将始终受到 GC 的影响。

您可以尝试通过使用适当的参数(例如 GC.MaxGeneration)调用 GC.Collect (C#) 来触发收集,但这仍然并不能保证 GC 不会工作在执行期间的其他时刻。

【讨论】:

  • 如果您使用非托管代码并且不受 GC 影响,您可以在 C# 中显式删除对象。 msdn.microsoft.com/en-us/library/t2yzs44b.aspx看来Java可能不同,因为它没有非托管模式。
  • @jdk:这没有抓住重点。没有人会完全用非托管 C# 代码编写 .NET 应用程序。如果他们这样做了,它就不再是一个 .NET 应用程序了,因为你不能真正使用 .NET 框架,也不能使用 C# 的很多功能。因此,虽然 C# 可以 删除固定对象是真的(实际上,VB 也可以,而无需求助于所谓的不安全代码),但这对日常开发没有帮助。
  • @Konrad:我不同意您的日常开发断言,只是您的原始帖子可能具有误导性。在作者关于“显式删除”的问题的上下文中,重要的是他要了解微软为程序员提供的所有可能性。我们不知道他打算如何使用这些知识。甚至大部分用非托管代码编写的应用程序都存在,这足以在此提及。
  • -1 - 显式调用垃圾收集器是个坏主意,因为(如果运行时系统注意调用)它很可能会使您的应用程序运行得更慢。
  • @Stephen C:完全正确。这就是为什么建议反对它。所以我不明白 -1。
【解决方案3】:

如果您的意思是释放对对象的引用,则通过显式“删除”,那么您依赖于 C# 托管代码中的垃圾收集器 - see the System.GC class 来控制它。

如果您选择编写非托管 C# 代码,那么您将对内存有更多控制权,类似于 C++,并负责删除您的实例化对象,能够使用指针等。有关更多信息,请参阅 MSDN doc - Unsafe Code and Pointers (C# Programming Guide)

在非托管代码中,您将不受垃圾收集器及其不确定的清理算法的支配。

我不知道 Java 是否具有等效的非托管模式,但此 Microsoft 信息可能有助于为 C#/.NET 提供一些指导,以使用其可用功能来满足您处理垃圾收集器的要求。

【讨论】:

  • 在 C# 中使用指针...好吧,只要您不依赖 MFCL 就可以了...您不太可能...如果您是那么为什么要使用那么任何托管语言...为什么不直接利用非托管环境的速度和功能...它可以为您提供更好的性能和速度。
  • 我同意你的评论;然而,我的回答是在作者关于垃圾收集器的关系和影响 C# 的问题的上下文中 - 非托管/托管模式对于了解这一点很重要。不幸的是,我也无法解决 Java 问题。此外,您可能会问微软同样的问题,因为他们为 C# 程序员提供了非托管模式。
  • @SMKamran - “非托管环境......更好的性能和速度”。是时候检查你的基本假设了——托管环境并不意味着性能差和执行速度慢。事实上,因为运行时有更多的可用信息和更大的适应范围,所以更多的优化是可能的。你不会相信我提供的任何参考资料 - 所以请去做一些真正的研究并检查你的事实。
  • @Bevan - 这是一场大肆宣传的辩论。但是与上下文中的问题无关。所以我会把它留到其他时间,也许……干杯。
  • @S M Kanran:“为什么要使用任何托管语言……为什么不直接利用非托管环境的速度和功能”。内存安全?
【解决方案4】:

在 Csharp 或 Java 中,您不能删除对象。您可以做的只是将它们标记为可删除。内存释放将由垃圾收集器完成。垃圾收集器可能不会在应用程序的生命周期内运行。但是它很可能会运行。当您的系统资源不足时,最有可能是运行时运行 GC 例程。而当资源不足时,GC 成为最高优先级的线程。所以你的申请确实生效了。但是,您可以通过计算应用程序生命周期内的正确负载和所需资源来最小化影响,并确保购买足够好的硬件。但你仍然不能只对自己的表现进行基准测试。

除了 GC 之外,由于涉及额外的委托层,托管应用程序确实比传统 C++ 应用程序稍微开销。并且由于运行时需要在您的应用程序启动之前启动并运行,所以第一次性能面板略有下降。

【讨论】:

    【解决方案5】:

    以下是使用 .net 紧凑框架开发实时系统的一些参考资料:

    他们都谈到了使用 .net 框架的内存要求。

    【讨论】:

      【解决方案6】:

      C# 和 Java 不适用于实时开发。然而,正如您所注意到的,软实时是可以实现的。

      对于 C#,你能做的最好的就是实现 finalize/dispose 模式:

      http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx

      您可以请求收集它,但通常最好确定如何执行此操作。

      http://msdn.microsoft.com/en-us/library/system.gc(VS.71).aspx

      对于 Java,有很多优化选项:

      http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

      与上述 IBM Metronome 等第三方解决方案一起使用。

      这是 CS 本身的一门真正的科学。

      【讨论】:

      • Java 和 C# 只是语言。 “GC 问题”是 JVM/CLR 实现的问题。
      • 谢谢。我不知道这一事实,并感谢像您这样在行业内拥有丰富知识的人提供的意见。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 2012-03-13
      • 1970-01-01
      • 2011-10-22
      • 2020-01-19
      • 2014-12-07
      • 2018-12-30
      相关资源
      最近更新 更多