Memory 关闭D垃圾收集器 我是C++程序员,考虑使用D来做一个我想玩的个人项目。我想知道是否有办法完全禁用垃圾收集器,以及这样做的风险是什么

Memory 关闭D垃圾收集器 我是C++程序员,考虑使用D来做一个我想玩的个人项目。我想知道是否有办法完全禁用垃圾收集器,以及这样做的风险是什么,memory,memory-management,d,garbage-collection,Memory,Memory Management,D,Garbage Collection,我知道我可以通过覆盖new和delete来使用malloc和free来管理自己的内存,但是如果我这样做了,我宁愿垃圾收集器根本不运行。如果您想使用malloc和free use。GC永远不会碰这些。包含内存管理所需的所有内容,包括disable() 不过GC并不是一件坏事。D中的大多数库(如果不是几乎所有的库的话)在代码中的某个地方没有显式删除内存,所以它不会让您成为英雄,但如果您有一些关键的性能要求,那么就可以了 GC使一切变得更加高效,比如数组切片和在参数中创建新对象,而无需调用方在任何地方

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

如果您想使用malloc和free use。GC永远不会碰这些。包含内存管理所需的所有内容,包括disable()

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


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

可以删除GC,并用一个简单的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无关的事情,因为它们会导致内存泄漏:

  • 不要使用array append(~=)运算符,或使用.length属性放大已分配的数组。如果必须重新分配旧数组,它们依赖于GC释放旧数组,因为在程序中的其他地方可能存在别名
  • 不要使用内置关联数组。释放这些数据的唯一方法是使用GC
  • 我相信,大多数火卫一和探戈的设计都假设存在垃圾收集。如果不使用GC,这些库中的函数可能会严重泄漏内存
  • 不要在禁用GC的情况下使用D2闭包。(无论如何,你不会为了一场比赛而这么做。)
  • 也就是说,虽然D被设计为在一些关键代码段(存在实时约束的关键代码段,您可能不应该使用任何形式的malloc,这些malloc不是为实时计算而明确设计的),但它在很大程度上是在假设GC存在的情况下设计的。在您的情况下,您仍然可以对所有初始化内容等使用GC,并且仅当您点击游戏中实际需要实时的部分时才禁用它


    顺便说一句,GC和手动内存管理可以在D中共存,并且在实践中,在优化代码时,手动删除一些具有平凡生命周期的大型对象可能会导致显著的加速。这可以类似于C++,使用DELATE语句,即使GC启用,也是安全的。当您没有实时限制时,这将为您提供GC的大部分好处以及手动内存管理的大部分性能。

    我正在阅读关于D语言的文章,我在D中发现了这一点:

    40更好的C -betterC是dmd的命令行标志,它限制编译器对某些运行时特性的支持。值得注意的是,用betterC编译的D程序或库与Druntime无关。编译时特性的使用没有任何限制。

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

    40.1后果 由于没有可用的Druntime,许多D特性将无法工作。例如:

    • 垃圾收集
    • 线程本地存储
    • TypeInfo和ModuleInfo
    • 班级
    • 内置螺纹(例如核心螺纹)
    • 动态数组(但不是切片)和关联数组
    • 例外情况
    • 用字符串切换
    • 最终开关
    • synchronized和core.sync
    • 静态模块构造函数或解构器
    • 解构器
    • 单元测试(测试可以像往常一样使用-betterC标志)

    另请参见

    有些语言功能需要GC,字符串连接和哈希表是一对。我不确定它们都是什么。关闭GC是有效的一种情况是,你可以证明你不会使用比实际更多的ram。我怀疑我是否真的会做很多数组切片或字符串操作。是否有依赖于GC的语言特性列表?也许我应该保持开启状态,然后避免使用这些功能。@BCS GC并不是真正的ram使用量,所以我不同意这一点,但它确实提供了一个很好的安全网。@BS:我会选择开启状态,避免需要GC的事情-似乎比随着时间的推移无意中泄漏少量内存更安全。是的,但这个项目将是一个游戏,游戏有严格的性能要求。我不能让GC在框架的中间运行。“你认为你能比机器更有效地管理内存吗?”是的,我是一个程序员。一些程序员编写了JavaGC。这不是管理内存的唯一方法。这很好,只是我不关心字符串性能。此外,它只是表明D的字符串实现比STLport的要好。事实上,D字符串是引用类型肯定与性能的提高比GC有更大的关系,尽管GC使这更容易。而且,我真的不喜欢那种你比我更了解我的问题领域的态度。我来这里不是为了一场关于GC的宗教辩论。我问了一个非常具体的问题。如果有人有更高的代表性,我会很感激他能消除所有这些OT噪音。如果你以60fps的速度跑步,1-3ms是一帧的6-18%。当G