我是一名C ++程序员,考虑将D用于我想要玩的个人项目。我想知道是否有办法完全禁用垃圾收集器,以及这样做的风险是什么。
我知道我可以通过覆盖new和delete来管理我自己的内存以使用malloc和free,但如果我这样做,我宁愿垃圾收集器根本不运行。
答案 0 :(得分:41)
要关闭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无关的事情,因为它们会导致内存泄漏:
那就是说,虽然D被设计为可以在几个关键代码段中禁用GC(存在实时约束的关键部分,你可能不应该使用任何形式的malloc而不是明确设计对于实时计算无论如何),它主要是在假设GC存在的情况下设计的。在您的情况下,您仍然可以将GC用于所有初始化内容等,并且只有当您点击实际需要实时的游戏部分时才禁用它。
作为旁注,GC和手动内存管理可以在D中共存,实际上,在优化代码时,手动删除一些具有微不足道的生命周期的大型对象可能会导致显着的加速。这可以使用delete语句与C ++类似地完成,即使启用了GC也可以安全地执行此操作。当您没有实时约束时,这将为您提供GC的大部分优势,并具有大部分手动内存管理性能。
答案 1 :(得分:8)
如果您想使用malloc并免费使用std.c.stdlib。 GC永远不会触及这些。 std.gc包含内存管理所需的所有内容,包括disable()。
然而,GC并不是一件坏事。大多数(如果不是几乎所有D中的库)都会在代码中的某个地方没有明确删除内存,所以它不会让你成为永远关闭它的英雄,但是如果你有一些关键的性能要求就可以。GC使得所有内容都更高效,如数组切片和在参数中创建新对象,而无需调用者在任何地方存储引用。好的代码要少得多,GC代码变得更小。
答案 2 :(得分:1)
可以删除GC并用malloc / free周围的简单包装替换。
答案 3 :(得分:1)
我正在阅读关于D语言的内容,我在D中看到了新的规范:
40。更好的C
-betterC是dmd的命令行标志,它限制编译器对某些运行时功能的支持。值得注意的是,使用betterC编译的D程序或库与Druntime没有关联。编译时功能的使用不受任何限制。 https://dlang.org/spec/betterc.html
使用此命令行标志的一个后果是禁用GC和语言功能中继。
40.1后果
由于没有可用的Druntime,许多D功能将无法使用。例如:
- 垃圾收集
- 线程本地存储
- TypeInfo和ModuleInfo
- 类
- 内置线程(例如core.thread)
- 动态数组(但不是切片)和关联数组
- 例外
- 使用字符串切换
- final switch
- synchronized和core.sync
- 静态模块构造函数或解构器
- 结构解构主义者
- unittest(测试可以和-betterC标志一样)