views:

135

answers:

4

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++?

+1  A: 

(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.

DK
IIRC, `delete` is deprecated in D2
Alexander Malakhov
+3  A: 

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.

dsimcha
I don't see what the slicing problem has to do with making unmanaged memory ugly. I accept the reasoning for making them reference types, but I just want to be able to say `Foo a = new Foo(); ... ; delete a;` without involving a GC.
Peter Alexander
You can't do that in D2; it was/will be specifically removed. Direct complaints regarding this to Andrei Alexandrescu.
DK
Can't do what? dsimcha mentioned several things. Are you saying that `scoped`, `emplace` and `malloc` have been removed/deprecated? EDIT: Oh, were you responding to my comment? I am aware that `delete` has been deprecated, but the syntax is not important; I would just like some way to easily allocate memory, and deallocate it manually without a GC getting in the way.
Peter Alexander
A: 

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.

Zuu
A: 

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?

Chris Nicholson-Sauls
Well, I need them for the same reason you need garbage collected class instances i.e. you want an object with reference semantics with a complex lifetime. The manual memory management part is for performance/memory usage concerns.
Peter Alexander
Memory usage should be the same, or so very near as to make no difference, whether you use GC'd memory or manually managed. As for performance, that depends on usage. If it's performance hits due to frequent allocations, one can use free-lists easily. If it's performance due to GC scans, then there isn't much to be done -- although even manually allocated classes will usually be registered for scanning, unless you are perfectly confident there is no need. Have you measured the impact of the GC on your case, to see how much it hurts?
Chris Nicholson-Sauls