我正在学习D语言,我喜欢它的很多功能,但我对GC有点怀疑。我想给它机会,但首先我想知道:
我具体询问当前D2运行时的GC。
我知道在某些情况下GC可以带来更好的性能,但是这个例子呢: 想象一下游戏引擎在游戏开始时分配大量内存(数百兆的复杂结构),但在游戏运行时它几乎不会进行任何分配/解除分配。但仍有一些事情发生(例如来自GUI中的字符串操作) - 那些最终会触发GC的小东西是否必须扫描所有已分配的内存?据我了解,即使我决定自己管理大部分数据的内存,如果我希望它能够保存对托管内存的任何引用(如字符串),我必须将范围注册到GC。
当然,我可以先编程并稍后进行配置,但我希望能够提前对性能进行至少一些估算。比以后采取一些变通办法更好。 (像免费列表这样的解决方案在我看来是丑陋的解决方法,无论如何都无法在任何地方使用。)
答案 0 :(得分:3)
我没有确切的答案,但这就是我能说的:
1)最确定的来源是gc的源代码: https://github.com/D-Programming-Language/druntime/blob/master/src/gc/gc.d (我很确定非常相似的gcx.d文件
2)当你进行gc分配时,可以预期gc运行(好吧,如果它认为需要分配一个新块,那么它会首先尝试收集现有的东西,但这是我的经验,在实践中,最好假设每个新的可以是一个gc集合),在程序终止时,以及其他任何地方 - 如果你不分配gc内存,gc实际上不会做任何事情。它不会阻止程序随机运行。
但是,如果你不知道在哪里看,它可能看似随机。检查本页底部: http://dlang.org/garbage.html
最常见到的是数组文字:auto x = [1,2,3];是一个运行时gc分配!有相当数量的phobos功能也可以进行gc分配,但不是全部。如果一个phobos函数返回一个数组(包括一个字符串),它分配的几率很高 - 如果没有别的,返回值可能是一个新的块,除非你知道你传递了一个缓冲区来接收数据。 / p>
也就是说,很多phobos实际上是免费分配的,每次发布都会变得更好。我相信所有std.algorithm和std.digest包现在都是免费分配的。所以你不必全力以赴,只要知道要避免哪些功能。
如果您编写了一个程序并希望找到隐藏的分配,我会使用调试器。在主循环之前设置断点。然后在gc_malloc和gc_qalloc设置断点并继续。如果它中断,请获取堆栈跟踪,现在您知道以后要避免的内容。
如果您的主循环是免费gc分配,它也将是免费的gc集合。
3)gc会扫描所有内存吗?不必要。有一个noscan标志,gc实现(参见源代码中的mark函数)可以跳过块。在druntime / src / rt / lifetime.d中,您可以看到此(此处称为BlkAttr.NO_SCAN)是基于TypeInfo设置的。这不是很精确,但我很确定它在大数组分配等方面设置正确。不应扫描您游戏的批量数据资产。
因此,它所花费的时间与它实际扫描的内存量成正比,这可能比你分配的量少得多。
答案 1 :(得分:1)
有人已经做过那种研究,并写了一篇关于它的文章:Real World Comparison, GC vs. Manual Memory Management - Benjamin Thaut。
BTW,可以在这里找到更多有用的文章:http://wiki.dlang.org/Articles。