dec*_*iar 5 garbage-collection memory-management d raii
我承认在这一点上我对D没有深刻的理解,我的知识纯粹依赖于我所阅读的文档和我尝试过的几个例子.
在C++中,您可以依赖RAII习惯用法在退出本地范围时调用对象的析构函数.
D你能来吗?
我理解D是一种垃圾收集语言,它也支持RAII.为什么以下代码不会清除内存,因为它离开了一个范围呢?
import std.stdio;
void main() {
{
const int len = 1000 * 1000 * 256; // ~1GiB
int[] arr;
arr.length = len;
arr[] = 99;
}
while (true) {}
}
Run Code Online (Sandbox Code Playgroud)
无限循环用于保持程序打开以使残留内存分配容易可见.
下面显示了C++中等效的相同程序的比较.

可以看出,C++在分配后立即清理了内存(刷新率使得它看起来好像分配了更少的内存),而D保留了它,即使它已经离开了范围.
因此,GC什么时候清理?
scope声明在D2中进行,所以我对语义并不十分肯定,但我想象的是,scope T[] a;只会在堆栈上分配数组结构(不用说,已经发生,无论如何scope).在他们要去的时候,不要使用范围(使用scope(exit)和朋友不同 - 继续使用它们).
动态数组总是使用GC来分配它们的内存 - 没有解决这个问题.如果你想要更具确定性的东西,使用std.container.Array将是最简单的方式,因为我认为你几乎可以将它放在你的scope vector3b array位置:
Array!vector3b array
只是不要费心将长度设置为零 - 一旦超出范围,内存将被释放(数组使用malloc /免费从libc下面).
不,您不能 假设垃圾收集器会在任何时间点收集您的对象。
然而,有一个delete关键字(以及一个scope关键字)可以确定性地删除对象。
scope用法如下:
{
scope auto obj = new int[5];
//....
} //obj cleaned up here
Run Code Online (Sandbox Code Playgroud)
和delete的使用方式与 C++ 类似(没有 的[]符号delete)。
不过,也有一些问题:
它并不总是能正常工作(我听说它不能很好地与数组一起工作)
D 的开发者(例如 Andrei)打算在以后的版本中删除它们,因为如果使用不当,它显然会弄乱事情。(我个人讨厌这一点,因为无论如何都很容易把事情搞砸,但他们坚持删除它,而且我认为人们无法说服他们,尽管如果是这样的话我会很高兴。)
取而代之的是,clear您已经可以使用一种方法,例如arr.clear();但是,我自己还不太确定它到底做了什么,但object.d如果您感兴趣,可以在 D 运行时查看源代码。
至于您的惊讶:我很高兴您感到惊讶,但考虑到它们都是本机代码,这并不奇怪。:-)