D 中的非托管内存管理
避免在 D 中使用 GC 的最佳方法是什么?有没有一种方法可以使用不涉及内存管理的类,或者是否必须像在 C 和 C++ 中那样使用指向 malloc 结构的指针?
What's the best way to avoid using GC in D? Is there a way to use classes that doesn't involve their memory being managed, or do you have to use pointers to malloc'd structs like you would in C and C++?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
很久以前就决定类需要是引用类型,因为切片问题。另一方面,D 是一种系统语言。因此,使用带有手动内存管理的类虽然丑陋但可行。
在 D2 + Phobos 中,您可以(不安全地)使用 std.typecons.scoped() 在堆栈上分配类实例。您可以(再次,不安全地)使用 std.conv.emplace() 在任意内存块中分配类。例如,可以使用 core.stdc.malloc() 创建分配类的内存块。但是,请注意,如果该类可能包含指向 GC 分配的内存的指针,则必须调用 GC.addRange()。
It was decided a long time ago that classes need to be reference types because of the slicing problem. On the other hand, D is a systems language. Therefore, using classes with manual memory management is ugly but do-able.
In D2 + Phobos, you can (unsafely) allocate a class instance on the stack using
std.typecons.scoped()
. You can (again, unsafely) allocate a class in any arbitrary memory block by usingstd.conv.emplace()
. The block of memory you allocate the class in can be created, for example, by usingcore.stdc.malloc()
. However, note that you will have to callGC.addRange()
if the class could possibly contain pointers into GC-allocated memory.(免责声明:我是一名 D 1.0 程序员,而不是 D 2.0)
本质上,您可以使用任何您想要在 D 中分配内存的函数。在 D 1.0 中,您可以 覆盖类的 new 运算符 并根据需要分配其内存;不过,我相信 D 2.0 中已将其删除。
您当然可以为类实例分配内存,适当地初始化它,然后转换为对象引用(尽管要小心隐藏的监视器引用)。
在更极端的情况下,您始终可以用 malloc 包装器替换 GC,这需要您手动管理所有内容(尽管我相信只有 D 1.0+Tango 才能减轻这种痛苦。)
最终,D 不会并不真正关心类实例的分配方式或位置;类引用只是衣服上的指针。只是不要对未通过
new
分配的对象使用delete
。(Disclaimer: I'm a D 1.0 programmer, not so much D 2.0)
At heart, you can use whatever function you want to allocate memory in D. In D 1.0, you can override the new operator for classes and allocate their memory however you want; I believe this is being removed in D 2.0, however.
You can certainly malloc memory for a class instance, initialise it as appropriate and then cast to an object reference (although do be careful about the hidden monitor reference).
In a more extreme case, you can always replace the GC with a malloc wrapper which requires you to manage everything manually (although I believe that only D 1.0+Tango makes this less that brutally painful.)
At the end of the day, D doesn't really care how or where your class instances are allocated; a class reference is just a pointer in a dress. Just don't use
delete
on an object you didn't allocate vianew
.前面的两个答案采用了这种方法来解释 D 在内存管理方面的功能是什么和不是什么。我不确定他们是否抓住了问题的本质。
但关于如何轻松实现手动内存管理的问题。我想说,使用 中的 malloc() 和 free() 的 C 版本std.c.stdlib。由此分配的任何内容都将被 GC 忽略。
为您的类重载 new 以使用 C stdlib 是可能的。
否则,您可以使用 typeinfo 数据手动将 ClassInfo.init 字节数组 memcpy 到手动管理的内存中。使用这种方法调用 ctor 可能会很棘手,但您可以决定使用普通函数而不是标准 ctor 名称。
然后将所有这些包装到一些方便的模板中,就可以了。
注:我也是 D1 人。
The two previous answers have taken the approach as to explain what D's capabilities are and what they are not, with regards to memory management. I'm not sure if they capture the essence of the question.
But with regards to the question of how to easily achieve manual memory managment. I would say, use the C version of malloc() and free() from the std.c.stdlib. Anything allocated by this, will be ignored by the GC.
Overloading new for your classes, to use the C stdlib is a possibility.
Otherwise you can use the typeinfo data to manually memcpy the ClassInfo.init byte array into your manually managed memory. Calling the ctor with this approach, might be tricky, but you could just decide to use an ordinary function instead of the standard ctor name.
Then wrap all this into some convenient templates, and you're set.
Note: I'm a D1 person aswell.
我很好奇为什么你特别需要手动管理类实例。我并不是想击倒你,我只是必须先了解你的情况,然后才能真正回答。结构是否有理由不能满足您的需求?这些对象是否逃离了它们的创建范围?这纯粹是频繁创建/销毁的问题,使用空闲列表可以作为解决方案吗?
I'm curious why you specifically need manually managed class instances. Not trying to shoot you down, I just would have to understand before I could really answer. Is there a reason why a struct would not suit your needs? Are these objects escaping the scope of their creation? Is it purely a matter of frequent creation/destruction, where using a free-list Could be a solution?