【问题标题】:Deterministic GC in the CLR?CLR中的确定性GC?
【发布时间】:2010-07-02 11:16:50
【问题描述】:

是否有任何具有确定性垃圾收集的 CLR 实现?

MS CLR GC 中的不确定性暂停会阻碍 .Net 成为适合实时开发的环境。

我知道,Java 中的 Metronome GC 和 BEA JRockit 是两种确定性 GC 实现。

但是有任何 .Net 等价物吗?

谢谢

【问题讨论】:

  • Windows 不是实时操作系统,因此显然 Microsoft CLR 很难为实时应用程序提供合适的环境。
  • @Brian 对 Windows XP 的第三方扩展可以使其成为实时操作系统。

标签: c# clr garbage-collection


【解决方案1】:

没有办法使 GC 具有确定性,当然希望使用计时器每秒准确地调用 GC.Collect() ;-)。

然而,GC 确实包含一个通知机制(从 .NET 3.5 SP1 开始),它允许您在第 2 代收集即将发生时收到通知。你可以阅读它here

GC 现在还包含多种延迟模式,可以防止发生任何 GC 收集。当然,您应该对此非常小心,但对实时系统特别有用。你可以阅读更多关于它的信息here

【讨论】:

  • 只是补充一点,这并不能使它具有确定性-它仍然可以随时调用自己,并且您不知道它将GC什么,或者需要多长时间。而且您的计时器将无法准确地每 250 毫秒计时一次。
  • 我希望那句话末尾的笑脸清楚地表明我并不认真。但说真的,每 250 毫秒调用一次GC.Collect()。是一个非常糟糕的主意。虽然以确定的间隔进行收集,但您的性能会很差,因为您会触发许多第 2 代收集。
  • @DayOne:这听起来是个真的坏主意。通过像这样调用 GC.Collect,您将定期强制执行最昂贵的收集类型。您的应用程序将花费比它需要的更多时间来收集。请记住,您的所有用户线程在收集的某些部分期间都会暂停。
  • @Steven:即使你的舌头在脸颊上(由于性能不佳),读者理解这一点很重要:调用 GC.Collect() 将不会免费当前无法访问的所有内容。至少,请GC.Collect(0, GCCollectionMode.Forced)GC.WaitForPendingFinalizers()GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced)。这个调用序列:获取最近的垃圾到它的终结器,等待那些终结器,然后收集所有代。即使那样,未使用的内存也可能不会释放回操作系统;页面可能仍被标记为保留供 .Net 特定使用。
  • 同样重要的是要意识到调用 GC.Collect() 过于频繁可能是有害的:它强制从第 0 代到第 1 代,最终到第 2 代,从而使其收集速度变慢。 在您完成主要计算序列之后,在关键点调用 GC.Collect(),并且不再对大量大型临时数据对象进行任何引用。这包括堆栈帧中没有引用;从主要计算方法返回后,可能需要将局部变量设置为“无”,或者仅在代码中从较高级别执行。
【解决方案2】:

不,没有。根据我的经验,.net 不能用于创建实时系统有很多原因,不仅仅是垃圾收集。 C 或 C++ 是更好的选择。此外,现代操作系统不提供确定性调度,它适用于所有应用程序,而与语言无关。

【讨论】:

    【解决方案3】:

    您必须自己控制 GC 以获得可预测的实时行为,但如果您这样做,那么您最好不要使用托管语言。

    对于实时系统,您需要控制正在运行的所有内容。对 Windows XP 进行了第三方修改,使其成为实时(但不记得是软实时还是硬实时)。

    完全不可行的选择。看看 Cosmos OS - 用 C# 编写并编译为我认为的汇编器 - 可能可以用它做点什么:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2019-08-16
      • 2023-04-06
      • 2021-01-22
      • 1970-01-01
      相关资源
      最近更新 更多