Deallocate array?

Steven Schveighoffer schveiguy at yahoo.com
Thu May 9 19:43:23 PDT 2013


On Thu, 09 May 2013 22:14:41 -0400, Ali Çehreli <acehreli at yahoo.com> wrote:

> On a 32-bit system string is 8 bytes (e.g. by pragma(msg,  
> string.sizeof)). So you have a single array of 800 million bytes. Then,  
> each of those strings point at 22 bytes of individully allocated memory  
> areas.

No, each array points at static data.  Strings are immutables stored in  
the data segment.

> Note that 800 million is about 20% of the entire addressable memory of  
> that system. If you have a single value that happens to look like a  
> pointer into that memory, that huge block will remain in memory forever.  
> The funny thing about dmd's current conservative GC is that even an  
> integer can be mistaken to be a pointer into that memory.
>
> So that's the problem today.

Correct, the only solution at the moment is to deallocate explicitly.

It is important to keep in mind that C# has a *precise* garbage collector,  
D has a *conservative* garbage collector.  C# will always do better than D  
at GC as long as this is true.

64 bit address space also helps tremendously.

> I don't know the exact requirement here but if you really must have 100  
> million strings at one time, then you may want to do your own memory  
> management. The following should work:
>
> import std.stdio;
> import core.memory;
>
> void main()
> {
>      enum size_t times = 10;
>      enum size_t stringCount = 100_000_000;
>
>      foreach (i; 0 .. times) {
>          auto rawMemory = cast(string*)GC.calloc(string.sizeof *  
> stringCount);
>
>          // D's cool feature of making a slice from raw pointer
>          auto tempArray = rawMemory[0 .. stringCount];

You can allocate normally, and just use free on the pointer

>
>          foreach (ref s; tempArray) {
>              s = "aaaaaaaaaaaaaaaaaaaaa";
>          }
>
>          GC.free(rawMemory);

GC.free(tempArray.ptr); // also works

>          // You may want to set tempArray to null at this point to  
> prevent
>          // using it accidentally but it is not necessary.
>
>          writefln("Done with allocation %s/%s; please press Enter",
>                   i + 1, times);
>          readln();
>      }
> }

-Steve


More information about the Digitalmars-d-learn mailing list