25

我是一名 C++ 程序员,正在考虑将 D 用于我想玩的个人项目。我想知道是否有办法完全禁用垃圾收集器,这样做有什么风险。

我知道我可以通过覆盖 new 和 delete 以使用 malloc 和 free 来管理我自己的内存,但如果我这样做了,我宁愿垃圾收集器根本不运行。

4

4 回答 4

43

在 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/探戈中:

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 无关的事情,因为它们会导致内存泄漏:

  1. 不要使用数组追加 ( ~= ) 运算符,或使用 .length 属性来扩大已分配的数组。如果必须重新分配旧数组,它们依赖 GC 来释放旧数组,因为程序中的其他地方可能存在别名。
  2. 不要使用内置的关联数组。释放这些的唯一方法是通过 GC。
  3. 大多数 Phobos 和我相信的 Tango 都是在假设存在垃圾收集的情况下设计的。如果不使用 GC,这些库中的函数可能会严重泄漏内存。
  4. 不要在禁用 GC 的情况下使用 D2 闭包。(无论如何,对于游戏而言,您都不会这样做。)

也就是说,虽然 D 被设计为在一些关键代码段中禁用 GC 时可用(存在实时约束的关键段,您可能不应该使用任何形式的 malloc 未明确设计为实时无论如何计算),它在很大程度上是在假设 GC 存在的情况下设计的。在您的情况下,您仍然可以将 GC 用于所有初始化内容等,并且仅在您点击游戏中实际需要实时的部分时才禁用它。

附带说明一下,GC 和手动内存管理可以在 D 中共存,实际上,在优化代码时,手动删除一些生命周期很短的大对象可以显着提高速度。这可以类似于 C++ 使用 delete 语句来完成,即使启用了 GC 也是安全的。当您没有实时限制时,这将为您提供 GC 的大部分好处以及手动内存管理的大部分性能。

于 2009-01-23T19:56:10.450 回答
8

如果您想使用 malloc 并免费使用std.c.stdlib。GC 永远不会碰这些。std.gc具有内存管理所需的所有内容,包括 disable()。

不过GC也不是坏事。D 中的大多数(如果不是几乎所有)库都会在代码中的某个地方没有显式删除内存,因此它不会让你成为英雄,让它一直关闭,但如果你有一些关键的性能要求,那就可以了。

GC 让一切都变得更有效率,比如数组切片和在参数中创建新对象,而无需调用者在任何地方存储对它们的引用。好的代码会少很多,而使用 GC 代码会变得更小。

于 2009-01-23T07:20:02.553 回答
2

我正在阅读有关 D 语言的内容,我在 D 中似乎新的规范中发现了这一点:

40. 更好的 C

-betterC 是 dmd 的命令行标志,它限制编译器对某些运行时特性的支持。值得注意的是,使用 betterC 编译的 D 程序或库不与 Druntime 链接。编译时特性的使用不受任何限制。 https://dlang.org/spec/betterc.html

使用此命令行标志的后果之一是禁用 GC 和在其上中继的语言功能。

40.1 后果

由于没有可用的 Druntime,许多 D 功能将无法工作。例如:

  • 垃圾收集
  • 线程本地存储
  • 类型信息和模块信息
  • 课程
  • 内置线程(例如 core.thread)
  • 动态数组(但不是切片)和关联数组
  • 例外
  • 用字符串切换
  • 最终开关
  • 同步和 core.sync
  • 静态模块构造函数或解构函数
  • 结构解构器
  • unittest(可以像往常一样使用 -betterC 标志进行测试)

另见https://dlang.org/blog/2017/08/23/d-as-a-better-c/

于 2018-01-02T22:35:45.543 回答
1

可以将 GC 移除并替换为 malloc/free 的简单包装器。

于 2009-01-23T16:32:26.680 回答