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++?
(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 via new
.
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 using std.conv.emplace()
. The block of memory you allocate the class in can be created, for example, by using core.stdc.malloc()
. However, note that you will have to call GC.addRange()
if the class could possibly contain pointers into GC-allocated memory.
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?