D 动态阵列 - RAII

发布于 2024-11-09 15:04:41 字数 628 浏览 4 评论 0原文

我承认目前我对 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) {}
}

存在无限循环是为了保持程序打开,使剩余内存分配易于可见。

下面显示了 C++ 中等效的相同程序的比较。 C++ v D

可以看到C++在分配后立即清理了内存(刷新率使得看起来好像少了一些)内存已分配),而 D 保留它,即使它已离开作用域。

那么,GC什么时候进行清理呢?

I admit I have no deep understanding of D at this point, my knowledge relies purely on what documentation I have read and the few examples I have tried.

In C++ you could rely on the RAII idiom to call the destructor of objects on exiting their local scope.

Can you in D?

I understand D is a garbage collected language, and that it also supports RAII.
Why does the following code not cleanup the memory as it leaves a scope then?

import std.stdio;

void main() {
      {
            const int len = 1000 * 1000 * 256; // ~1GiB

            int[] arr;
            arr.length = len;
            arr[] = 99;
      }

      while (true) {}
}

The infinite loop is there so as to keep the program open to make residual memory allocations easy visible.

A comparison of a equivalent same program in C++ is shown below.
C++ v D

It can be seen that C++ immediately cleaned up the memory after allocation (the refresh rate makes it appear as if less memory was allocated), whereas D kept it even though it had left scope.

Therefore, when does the GC cleanup?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离去的眼神 2024-11-16 15:04:41

scope 声明在 D2 中,所以我不太确定语义,但我想象正在发生的是 scope T[] a; 只分配堆栈上的数组结构(不用说,无论范围如何,这已经发生了)。正如他们所说,不要使用作用域(使用 scope(exit) 和朋友 是不同的——继续使用它们)。

动态数组总是使用 GC 来分配内存——这是无法回避的。如果您想要更具确定性的东西,请使用 std.container.Array 将是最简单的方式,因为我认为您几乎可以将其放在 scope vector3b array 所在的位置:

Array!vector3b array

只是不要不必将长度设置为零——一旦超出范围,内存就会被释放(数组在底层使用 libc 中的 malloc/free )。

scope declarations are going in D2, so I'm not terribly certain on the semantics, but what I'd imagine is happening is that scope T[] a; only allocates the array struct on the stack (which needless to say, already happens, regardless of scope). As they are going, don't use scope (using scope(exit) and friends is different -- keep using them).

Dynamic arrays always use the GC to allocate their memory -- there's no getting around that. If you want something more deterministic, using std.container.Array would be the simplest manner, as I think you could pretty much drop it in where your scope vector3b array is:

Array!vector3b array

Just don't bother setting the length to zero -- the memory will be free'd once it goes out of scope (Array uses malloc/free from libc under the hood).

放血 2024-11-16 15:04:41

不,您不能假设垃圾收集器会在任何时间点收集您的对象。

但是,有一个 delete 关键字(以及 scope 关键字)可以确定性地删除对象。

scope 的使用方式如下:

{
    scope auto obj = new int[5];
    //....
} //obj cleaned up here

delete 的使用方式类似于 C++(delete 没有 [] 表示法)。

不过,也有一些问题:

  • 它并不总是能正常工作(我听说它不能很好地与数组一起工作)

  • D 的开发者(例如 Andrei)打算在以后的版本中删除它们,因为如果使用不正确,它显然会弄乱事情。 (我个人讨厌这一点,因为无论如何都很容易把事情搞砸,但他们坚持删除它,而且我认为人们无法说服他们,尽管我很喜欢它如果是这样的话。)

  • 在它的位置,已经有一个 clear 方法可供您使用,例如 arr.clear();但是,我自己还不太确定它到底做了什么,但是如果您感兴趣,您可以查看 D 运行时中的 object.d 中的源代码。


至于您的惊讶:我很高兴您感到惊讶,但考虑到它们都是本机代码,这并不奇怪。 :-)

No, you cannot assume that the garbage collector will collect your object at any point in time.

There is, however, a delete keyword (as well as a scope keyword) that can delete an object deterministically.

scope is used like:

{
    scope auto obj = new int[5];
    //....
} //obj cleaned up here

and delete is used like in C++ (there's no [] notation for delete).

There are some gotcha's, though:

  • It doesn't always work properly (I hear it doesn't work well with arrays)

  • The developers of D (e.g. Andrei) are intending to remove them in later versions, because it can obviously mess up things if used incorrectly. (I personally hate this, given that it's so easy to screw things up anyway, but they're sticking with removing it, and I don't think people can convince them otherwise although I'd love it if that was the case.)

  • In its place, there is already a clear method that you can use, like arr.clear(); however, I'm not quite sure what it exactly does yet myself, but you could look at the source code in object.d in the D runtime if you're interested.


As to your amazement: I'm glad you're amazed, but it shouldn't be really surprising considering that they're both native code. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文