可以调用core.memory的GC.collect来保持更一致的帧速率吗?

Ver*_*gon 3 garbage-collection d frame-rate real-time

我正在研究使用OpenGL和D进行实时游戏,我担心垃圾收集器.从我听到的情况来看,这是一种可能性:

  • 运行10帧
  • 垃圾收集器自动运行并运行10毫秒
  • 运行10帧
  • 垃圾收集器自动运行并运行10毫秒
  • 运行10帧
  • 等等

这可能很糟糕,因为它导致口吃.但是,如果我强制垃圾收集器一直运行,就像GC.collect一样,它会让我的游戏更顺畅吗?像这样:

  • 1帧运行
  • 垃圾收集器运行1-2ms
  • 1帧运行
  • 垃圾收集器运行1-2ms
  • 1帧运行
  • 等等

这种方法是否真的有效并使我的帧率更加一致?我想使用D,但如果我不能使我的帧率保持一致,那么我将不得不使用C++ 11.

我意识到它可能效率不高,但重要的是它会更平滑,更稳定的帧速率.如果你知道我的意思,我宁愿平滑30 fps而不是口吃35 fps.

Vla*_*eev 6

是的,但它可能不会产生显着的差异.

在GC循环中花费的大部分时间是"标记"阶段,其中GC从根区域(静态数据,TLS,堆栈和寄存器)传递地访问每个分配的存储块(已知包含指针).

有几种方法可以优化应用程序的内存,因此D的GC对性能的影响较小:

  • 使用批量分配(批量分配对象作为数组)
  • 使用自定义分配器(std.allocator正在运行,但您可以使用自己的或第三方解决方案)
  • 使用手动内存管理,就像在C++中一样(您可以RefCounted像使用一样使用shared_ptr)
  • 在游戏过程中完全避免内存分配,并事先预先分配所有内容
  • 禁用GC,并在更方便时手动运行集合

一般来说,我不建议在编写任何代码之前关注GC.D提供了避免大量GC分配的工具.如果保持托管堆较小,GC周期可能不会花费足够长的时间来干扰应用程序的响应能力.

  • 我认为重要的是要提到一个集合只能通过GC操作启动(比如使用GC分配).如果您可以确保在游戏过程中从不使用GC(您仍然可以在加载/启动阶段使用它),那么GC将无法启动. (2认同)