我是一名C++程序员,考虑将D用于我想要玩的个人项目.我想知道是否有办法完全禁用垃圾收集器,以及这样做的风险是什么.
我知道我可以通过覆盖new和delete来管理我自己的内存以使用malloc和free,但如果我这样做,我宁愿垃圾收集器根本不运行.
要在D2中关闭GC:
import core.memory; void main(string[] args) { GC.disable; // Do stuff. }
如果使用D1/Phobos:
import std.gc; void main(char[][] args) { std.gc.disable; // Do stuff. }
在D1/Tango中:
import tango.core.Memory; void main(char[][] args) { GC.disable; // Do stuff. }
可以通过调用GC.enable(D2或D1/Tango)或std.gc.enable(D1/Phobos)来类似地重新启用GC.这些可以在程序中的任何一点完成.在内部,使用计数器,并且为了实际重新启用GC,每次调用disable()时都必须调用enable()一次.
以下是一些与GC禁用无关的事情,因为它们会导致内存泄漏:
不要使用数组append(〜=)运算符,或使用.length属性放大已分配的数组.如果必须重新分配,这些依赖于GC来释放旧数组,因为程序中的其他地方可能存在别名.
不要使用内置关联数组.解决这些问题的唯一方法是通过GC.
大多数Phobos和我相信Tango的设计都假设存在垃圾收集.如果不使用GC,这些库中的函数可能会泄漏内存.
禁用GC时不要使用D2闭包.(不管怎么说,对于一场比赛,你不会这么做.)
也就是说,虽然D被设计为可以在几个关键代码中禁用GC(存在实时约束的关键部分,你可能不应该使用任何形式的malloc而不是为实时设计无论如何计算,它主要是在假设GC存在的情况下设计的.在您的情况下,您仍然可以将GC用于所有初始化内容等,并且只有当您点击实际需要实时的游戏部分时才禁用它.
作为旁注,GC和手动内存管理可以在D中共存,并且在实践中,在优化代码时,手动删除具有微不足道的生命周期的一些大对象可以导致显着的加速.这可以使用delete语句与C++类似地完成,即使启用了GC也可以安全地执行此操作.当您没有实时约束时,这将为您提供GC的大部分优势,具有大多数手动内存管理性能.
如果要使用malloc并免费使用std.c.stdlib.GC永远不会触及这些.std.gc具有内存管理所需的所有内容,包括disable().
GC并不是一件坏事.大多数(如果不是几乎所有D中的库)都会在代码中的某个地方没有明确删除内存,所以它不会让你成为一个英雄,让它永远关闭但是如果你有一些关键性能要求就可以了.
GC使得所有内容都更高效,如数组切片和在参数中创建新对象,而无需调用者在任何地方存储引用.良好的代码要少得多,GC代码变得更小.