【问题标题】:C# and .Net Garbage collector performanceC# 和 .Net 垃圾收集器性能
【发布时间】:2013-04-20 08:13:39
【问题描述】:

我正在尝试用 C# 和 .NET 制作游戏,并计划实现更新游戏世界中游戏对象的消息。这些消息将是 C# 引用对象。

我想要这种方法,因为如果我想让游戏成为多人游戏,这样做会更容易通过网络发送它们。

但是如果我有很多消息,垃圾收集器会不会很紧张?这不会影响游戏玩法吗?消息类本身非常小,最多只有 4 或 5 个成员。

这些消息将每秒为游戏世界中的每个对象生成几次。

【问题讨论】:

  • .net 中的 GC 是分代的。假设消息是短暂的,那么它们应该主要在 0 级生成中收集。如果是这样,性能应该不会太差:)
  • 你可以在这里询问更好的答案gamedev.stackexchange.com
  • 通过网络传输所有这些消息的开销将成为限制因素;相比之下,GC 的开销可能可以忽略不计。
  • 你应该问问自己这些消息对象应该存在多长时间。如果他们很少离开 gen0,那么应该没有问题。我建议阅读this
  • 与大多数性能问题一样:构建并衡量。

标签: c# garbage-collection


【解决方案1】:

在 .NET 中,垃圾收集器有 3 代,第 0 代、第 1 代和第 2 代。每次 GC 未能在一代中收集对象时,该对象将被提升到下一代。

如果您的对象大于 85kb,您可能会遇到问题。这些对象将自动存储在大对象堆中。大对象堆会在以下情况被自动回收:

  • 分配超过大对象堆阈值。
  • 系统内存不足。
  • System.GC.Collect 在第 2 代被调用。

问题是当收集大对象堆时,对象的内存被释放但 LOH 没有被压缩。由于 LOH 是碎片化的,如果 LOH 上没有足够大的空间容纳您的对象,您可能会抛出 SystemOutOfMemory 异常。

对象池等技术通常用于提高 LOH 的性能。 http://en.wikipedia.org/wiki/Object_pool_pattern

来源:http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

更新:.Net 4.5.1 将允许您使用 GC.Collect API 在应用程序中按需压缩 LOH。

【讨论】:

  • 这是一个了不起的答案,我不知道为什么它没有得到更多的支持。澄清了很多关于 GC 的工作原理(其中大部分我不知道)。 +1
  • 您提供的链接已有 5 年历史,涉及 .NET 1.0 和 2.0;您知道框架 4.0+ 是否也是如此?谢谢
  • 刚刚找到这个关于 .NET 4.5 中 LOH 更改的链接; blogs.msdn.com/b/dotnet/archive/2011/10/04/…
【解决方案2】:

更高版本的 GC,更准确地说是 4.5,对 0 和 1 代异步运行。这大大降低了 GC 的影响。

如果您的对象是短暂的,它们大多数时候不应从第 0 代传递。 0 级是 GC 清理速度最快的一代。

底线,我不会考虑过早优化我的代码,因为担心 GC 性能。

过早的优化是万恶之源 DonaldKnuth

就个人而言,我会推荐这个article 以加深理解

【讨论】:

  • 这真的很有帮助。我本来打算在 .net 4.5 上制作游戏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多