我是一名 C++ 程序员,正在考虑将 D 用于我想玩的个人项目。我想知道是否有办法完全禁用垃圾收集器,这样做有什么风险。
我知道我可以通过覆盖 new 和 delete 以使用 malloc 和 free 来管理我自己的内存,但如果我这样做了,我宁愿垃圾收集器根本不运行。
我是一名 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/探戈中:
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 中共存,实际上,在优化代码时,手动删除一些生命周期很短的大对象可以显着提高速度。这可以类似于 C++ 使用 delete 语句来完成,即使启用了 GC 也是安全的。当您没有实时限制时,这将为您提供 GC 的大部分好处以及手动内存管理的大部分性能。
如果您想使用 malloc 并免费使用std.c.stdlib。GC 永远不会碰这些。std.gc具有内存管理所需的所有内容,包括 disable()。
不过GC也不是坏事。D 中的大多数(如果不是几乎所有)库都会在代码中的某个地方没有显式删除内存,因此它不会让你成为英雄,让它一直关闭,但如果你有一些关键的性能要求,那就可以了。
GC 让一切都变得更有效率,比如数组切片和在参数中创建新对象,而无需调用者在任何地方存储对它们的引用。好的代码会少很多,而使用 GC 代码会变得更小。
我正在阅读有关 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 标志进行测试)
可以将 GC 移除并替换为 malloc/free 的简单包装器。