www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Garbage collector doesn't collect?

reply n00b <n00b nospam.com> writes:
If I do the following... :

foreach(string foo ; bigFilesList)
{
	string file = cast(string)std.file.read(foo);
}

...I run out of memory because the garbage collector apparently does not 
free previously loaded files, even though there isn't any reference left 
to them. ( I'm using D2.59, later versions do not seem to work with 
visualD )
Is it a bug?
Jan 29 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 29 January 2013 at 15:43:00 UTC, n00b wrote:
 If I do the following... :

 foreach(string foo ; bigFilesList)
 {
 	string file = cast(string)std.file.read(foo);
 }

 ...I run out of memory because the garbage collector apparently 
 does not free previously loaded files, even though there isn't 
 any reference left to them. ( I'm using D2.59, later versions 
 do not seem to work with visualD )
 Is it a bug?
AFAIK, this is a limitation for win32, where the GC mistakes random bit patterns for pointers, and then refuses to release the memory. If I'm not mistaken, the "classic" workaround is to manually allocate (using the GC), but telling it to not scan. This way, you still have a safelly GC allocated array, but it gets correctly collected: http://dlang.org/phobos/core_memory.html //---- //Original string string file = cast(string)std.file.read(foo); //allocate new string immutable len = file.length; void* p = GC.malloc(file.length, GC.BlkAttr.NO_SCAN); char[] newString = (cast(char*)p) [0 .. len]; //Copy string newString[] = file[]; //release old string GC.free(cast(void*)file.ptr); //place new string into old file = cast(string) newString; //---- Note that if you don't need "file" at the end of the loop, you can just explicitly release file and move on, rather than do all that. ... I think.
Jan 29 2013