www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Freeing of memory (garbage collection)

reply Dan W <twinbee42 skytopia.com> writes:
A couple of questions:

1: Even though D has an automatic garbage collector, is one still
allowed to free the memory of a malloced array manually (using free
() ), to avoid pauses in the program?

2: One justification on the website for using automatic garbage
collection is how "allocated memory will only be freed if system RAM
is tight". But surely that's silly, since one may want *lots* of
memory free for a completely different application (merely memory
being 'tight' before freeing may not be good enough - one may want D
to free memory sooner).
Dec 08 2008
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Dan,

 A couple of questions:
 
 1: Even though D has an automatic garbage collector, is one still
 allowed to free the memory of a malloced array manually (using free ()
 ), to avoid pauses in the program?
 

Yes, in fact if you malloc memory you MUST free it. Only stuff like dynamic arrays, AAs and new'ed stuff gets cleaned up by the GC.
 2: One justification on the website for using automatic garbage
 collection is how "allocated memory will only be freed if system RAM
 is tight". But surely that's silly, since one may want *lots* of
 memory free for a completely different application (merely memory
 being 'tight' before freeing may not be good enough - one may want D
 to free memory sooner).
 

With virtual memory and swap space, this (almost) no longer matters. If you aren't using memory sooner or later it's not using your RAM but just sitting on the disk.
Dec 08 2008
parent reply Daniel White <twinbee42 skytopia.com> writes:
Thanks for that reply. I wonder if extending automatic garbage
collection for malloced memory would be a good idea...

 Only stuff like dynamic 
 arrays, AAs and new'ed stuff gets cleaned up by the GC.

For the above types of allocating memory, is there a way to 'lock' a variable and say to D, "don't free this memory until I allow you to", and also for it to allow you to free it manually when/if need be?
Dec 09 2008
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Daniel White" wrote
 Thanks for that reply. I wonder if extending automatic garbage
 collection for malloced memory would be a good idea...

 Only stuff like dynamic
 arrays, AAs and new'ed stuff gets cleaned up by the GC.

For the above types of allocating memory, is there a way to 'lock' a variable and say to D, "don't free this memory until I allow you to", and also for it to allow you to free it manually when/if need be?

One thing you can do, that nobody has mentioned yet, is delete memory that you have allocated using the GC. Deleting a block of memory that the GC has allocated allows you to reuse that memory without going through a full GC collect cycle, and so most likely your performance will be better. Using delete in key spots can be good. But using manual memory mangement prevents lots of good designs, so use with caution. Lastly, if you are allocating lots of temporary classes, try declaring them as scope. This allocates the class on the stack if possible. Note that any memory allocated by the constructor will still go through the GC. Also note that you can't use a scoped class once its scope is finished. e.g.: class C { ... } ... while(x > 0) { scope c = new C(x--); // c is allocated on the stack. scope keyword implies the type. c.doSomething(); // c is deleted from stack at end of loop iteration. No heap activity. } -Steve
Dec 09 2008
parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:
 One thing you can do, that nobody has mentioned yet, is delete memory that 
 you have allocated using the GC.

Leaving the GC manage and free your memory is usually OK. Managing manually your memory allocated from the C heap is doable. But freeing manually and forcefully memory allocated by the GC seems dangerous to me. Bye, bearophile
Dec 09 2008
prev sibling parent reply Daniel White <twinbee42 skytopia.com> writes:
 That would be a bad idea.  Then how would you do manual memory
 management in the few cases that absolutely require it?

Two ways. Either: a: being able to lock the variable so that the garbage collector can't touch it until you unlock it. b: Using a slightly different version of malloc (say 'mallocl') which again, makes it shielded against the garbage collector's wrath.
Dec 09 2008
next sibling parent Daniel White <twinbee42 skytopia.com> writes:
Jarrett Billingsley Wrote:

 On Tue, Dec 9, 2008 at 11:08 AM, Daniel White <twinbee42 skytopia.com> wrote:
 That would be a bad idea.  Then how would you do manual memory
 management in the few cases that absolutely require it?

Two ways. Either: a: being able to lock the variable so that the garbage collector can't touch it until you unlock it.

Why not just use GC-allocated memory and use addRoot then?

Well that question points at the deeper issue of why bother having malloc at all.
Dec 09 2008
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Daniel White wrote:
 That would be a bad idea.  Then how would you do manual memory
 management in the few cases that absolutely require it?

Two ways. Either: a: being able to lock the variable so that the garbage collector can't touch it until you unlock it.

If you have a reference to the memory, the GC won't collect it. Unless you make a habit of hiding pointers inside non-pointer types, that is, which can result in undefined behavior if the hidden pointer points to GC-allocated memory. If you don't have any reference to that memory, then the garbage collector can free it, but in that case, I don't see why it would be an issue, most of the time. If you have a destructor, just be careful -- for instance, if you have an open file in that object and its destructor closes that file.
 b: Using a slightly different version of malloc (say 'mallocl') which again,
 makes it shielded against the garbage collector's wrath.

malloc is C stdlib malloc. The garbage collector won't touch it.
Dec 09 2008
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Dan W:
 1: Even though D has an automatic garbage collector, is one still
 allowed to free the memory of a malloced array manually (using free
 () ), to avoid pauses in the program?

Other people here will just answer your question. But remember that in D manual memory management is done only in special situations, most code of most programs just use the GC. Bye, bearophile
Dec 09 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Dec 9, 2008 at 9:16 AM, Daniel White <twinbee42 skytopia.com> wrote:
 Thanks for that reply. I wonder if extending automatic garbage
 collection for malloced memory would be a good idea...

That would be a bad idea. Then how would you do manual memory management in the few cases that absolutely require it?
 Only stuff like dynamic
 arrays, AAs and new'ed stuff gets cleaned up by the GC.

For the above types of allocating memory, is there a way to 'lock' a variable and say to D, "don't free this memory until I allow you to", and also for it to allow you to free it manually when/if need be?

Yes, you can use std.gc.addRoot in Phobos (in D1), and GC.addRoot if you're using Tango (import tango.core.Memory) or D2 (import core.memory).
Dec 09 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Dec 9, 2008 at 9:42 AM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
 On Tue, Dec 9, 2008 at 9:16 AM, Daniel White <twinbee42 skytopia.com> wrote:
 Thanks for that reply. I wonder if extending automatic garbage
 collection for malloced memory would be a good idea...

That would be a bad idea. Then how would you do manual memory management in the few cases that absolutely require it?
 Only stuff like dynamic
 arrays, AAs and new'ed stuff gets cleaned up by the GC.

For the above types of allocating memory, is there a way to 'lock' a variable and say to D, "don't free this memory until I allow you to", and also for it to allow you to free it manually when/if need be?

Yes, you can use std.gc.addRoot in Phobos (in D1), and GC.addRoot if you're using Tango (import tango.core.Memory) or D2 (import core.memory).

Oh yeah, and you can use 'delete' on arrays, classes, and structs allocated on the heap, but oddly not with AAs.
Dec 09 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Dec 9, 2008 at 11:08 AM, Daniel White <twinbee42 skytopia.com> wrote:
 That would be a bad idea.  Then how would you do manual memory
 management in the few cases that absolutely require it?

Two ways. Either: a: being able to lock the variable so that the garbage collector can't touch it until you unlock it.

Why not just use GC-allocated memory and use addRoot then?
 b: Using a slightly different version of malloc (say 'mallocl') which again,
 makes it shielded against the garbage collector's wrath.

At which point you're back to the same situation as we have currently.
Dec 09 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Dec 9, 2008 at 2:53 PM, Daniel White <twinbee42 skytopia.com> wrote:
 Jarrett Billingsley Wrote:

 On Tue, Dec 9, 2008 at 11:08 AM, Daniel White <twinbee42 skytopia.com> wrote:
 That would be a bad idea.  Then how would you do manual memory
 management in the few cases that absolutely require it?

Two ways. Either: a: being able to lock the variable so that the garbage collector can't touch it until you unlock it.

Why not just use GC-allocated memory and use addRoot then?

Well that question points at the deeper issue of why bother having malloc at all.

For interaction with some C libraries. Or for implementing your own memory management without having to deal with the GC.
Dec 09 2008
prev sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Tue, 9 Dec 2008 03:25:07 +0000 (UTC), Dan W wrote:

 1: Even though D has an automatic garbage collector, is one still
 allowed to free the memory of a malloced array manually (using free
 () ), to avoid pauses in the program?

Just to clarify. There are 3 types of allocation: 1. std.c.stdlib.malloc(). The good ol' plain C allocation which is entirely manual and requires std.c.stdlib.free() to free memory. 2. std.gc.malloc(), or tango.core.Memory.GC.malloc(), or core.memory.GC.malloc() in recent D2. These allocate an uninitialized but GC-managed and GC-scanned by default memory. That is, this memory gets automatically freed as soon as there are no GC-managed references to it. You can explicitly free this memory using the delete keyword. You can direct GC not to scan this memory for pointers using std.gc.hasNoPointers() or equivalent. 3. Memory allocated via new, arrays, etc. This memory is GC-managed but can be freed explicitly using the delete keyword.
 2: One justification on the website for using automatic garbage
 collection is how "allocated memory will only be freed if system RAM
 is tight". But surely that's silly, since one may want *lots* of
 memory free for a completely different application (merely memory
 being 'tight' before freeing may not be good enough - one may want D
 to free memory sooner).

I don't think this is a valid justification. One of the main GC justifications is an ability to implement flexible data models where data owner is uncertain or unknown. In such cases GC makes it easy to avoid data duplication.
Dec 13 2008