www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - using D without GC

reply "Oleg B" <code.viator gmail.com> writes:
Hello. I want to try use D without GC and I'm not sure what I do 
all right.

import core.memory;

version( gcdis ) enum gc_disable = true;
else             enum gc_disable = false;

class Foo
{
     byte[][] buf;
     this()
     {
         foreach( i; 0 .. 32 )
             buf ~= new byte[]( 65536 * 16 );
     }
     ~this()
     {
         static if( gc_disable )
         {
             // no warning about deprecated 'delete'
             foreach( i; 0 .. 32 )
                 delete buf[i];
             delete buf;
         }
     }
}

void main()
{
     static if( gc_disable ) GC.disable();

     foreach( i; 0 .. 200 )
         scope foo = new Foo;

     static if( gc_disable )
     {
         GC.enable();
         GC.collect();
     }
}

dmd -version=gcdis test.d && ./test "--DRT-gcopt=profile:1"
	Number of collections:  2
	Total GC prep time:  0 milliseconds
	Total mark time:  0 milliseconds
	Total sweep time:  0 milliseconds
	Total page recovery time:  0 milliseconds
	Max Pause Time:  0 milliseconds
	Grand total GC time:  0 milliseconds
GC summary:   51 MB,    2 GC    0 ms, Pauses    0 ms <    0 ms

dmd test.d && ./test "--DRT-gcopt=profile:1"
	Number of collections:  205
	Total GC prep time:  1 milliseconds
	Total mark time:  1 milliseconds
	Total sweep time:  5 milliseconds
	Total page recovery time:  0 milliseconds
	Max Pause Time:  0 milliseconds
	Grand total GC time:  8 milliseconds
GC summary:   69 MB,  205 GC    8 ms, Pauses    3 ms <    0 ms

I use this feature correctly?
Jun 07 2015
next sibling parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 7/06/2015 10:16 p.m., Oleg B wrote:
 Hello. I want to try use D without GC and I'm not sure what I do all right.

 import core.memory;

 version( gcdis ) enum gc_disable = true;
 else             enum gc_disable = false;

 class Foo
 {
      byte[][] buf;
      this()
      {
          foreach( i; 0 .. 32 )
              buf ~= new byte[]( 65536 * 16 );
      }
      ~this()
      {
          static if( gc_disable )
          {
              // no warning about deprecated 'delete'
              foreach( i; 0 .. 32 )
                  delete buf[i];
              delete buf;
          }
      }
 }

 void main()
 {
      static if( gc_disable ) GC.disable();

      foreach( i; 0 .. 200 )
          scope foo = new Foo;

      static if( gc_disable )
      {
          GC.enable();
          GC.collect();
      }
 }

 dmd -version=gcdis test.d && ./test "--DRT-gcopt=profile:1"
      Number of collections:  2
      Total GC prep time:  0 milliseconds
      Total mark time:  0 milliseconds
      Total sweep time:  0 milliseconds
      Total page recovery time:  0 milliseconds
      Max Pause Time:  0 milliseconds
      Grand total GC time:  0 milliseconds
 GC summary:   51 MB,    2 GC    0 ms, Pauses    0 ms <    0 ms

 dmd test.d && ./test "--DRT-gcopt=profile:1"
      Number of collections:  205
      Total GC prep time:  1 milliseconds
      Total mark time:  1 milliseconds
      Total sweep time:  5 milliseconds
      Total page recovery time:  0 milliseconds
      Max Pause Time:  0 milliseconds
      Grand total GC time:  8 milliseconds
 GC summary:   69 MB,  205 GC    8 ms, Pauses    3 ms <    0 ms

 I use this feature correctly?
Don't worry about collecting at the end. The OS will clean up the app no matter what. You shouldn't be using delete or new for that matter. You should be using malloc + free. And emplace. Also you don't need to enable the GC before telling it to collect. I can't really help with emplace usage. But for the record the GC isn't going to slow you down here. No just reserve some memory and preallocate the buffer you want before using it. It'll be a lot faster and cheaper. Concatenation is your real enemy here. Aka realloc.
Jun 07 2015
next sibling parent reply "Oleg B" <code.viator gmail.com> writes:
 No just reserve some memory and preallocate the buffer you want 
 before using it. It'll be a lot faster and cheaper.
I know, it's only for test.
 You shouldn't be using delete or new for that matter.
 You should be using malloc + free. And emplace.
auto myalloc(T)( size_t count ) { struct Impl{ size_t len; void* ptr; } union Wrap { Impl impl; T[] arr; } auto ret = Wrap( Impl( count, calloc( count, T.sizeof ) ) ).arr; enforce( ret.ptr !is null ); return ret; } class Bar { float[] buf; this() { buf = myalloc!float( 65536 ); } ~this() { free(buf.ptr); } } For simple types arrays all clear. Emplace realization not trivial for me yet. As I understand correctly it concerns placing initial values of struct for example or values before calling ctor in place to array segment without copying? But what I need use for class objects? class Foo { Bar[] buf; this() { buf = myalloc!Bar( 100 ); // I think it's ok foreach( ref b; buf ) b = new Bar; // but calloc can't initialize class correctly } ~this() { static if( gc_disable ) { foreach( ref b; buf ) delete b; free(buf.ptr); } } } Operator new automatically allocate range in GC-manage memory? If it is whether is possible to change this behavior? It's question relates to emplace too?
Jun 07 2015
next sibling parent "Alex Parrill" <initrd.gz gmail.com> writes:
On Sunday, 7 June 2015 at 16:25:29 UTC, Oleg B wrote:
 auto myalloc(T)( size_t count )
 {
     struct Impl{ size_t len; void* ptr; }
     union Wrap { Impl impl; T[] arr; }
     auto ret = Wrap( Impl( count, calloc( count, T.sizeof ) ) 
 ).arr;
     enforce( ret.ptr !is null );
     return ret;
 }
Note that you can slice non-gc memory. `Impl` is basically what a slice is internally. auto ret = calloc(count, T.sizeof)[0..(count*T.sizeof)]
Jun 07 2015
prev sibling parent reply "Andrea Fontana" <nospam example.com> writes:
On Sunday, 7 June 2015 at 16:25:29 UTC, Oleg B wrote:
 No just reserve some memory and preallocate the buffer you 
 want before using it. It'll be a lot faster and cheaper.
I know, it's only for test.
 You shouldn't be using delete or new for that matter.
 You should be using malloc + free. And emplace.
auto myalloc(T)( size_t count ) { struct Impl{ size_t len; void* ptr; } union Wrap { Impl impl; T[] arr; } auto ret = Wrap( Impl( count, calloc( count, T.sizeof ) ) ).arr; enforce( ret.ptr !is null ); return ret; } class Bar { float[] buf; this() { buf = myalloc!float( 65536 ); } ~this() { free(buf.ptr); } } For simple types arrays all clear. Emplace realization not trivial for me yet. As I understand correctly it concerns placing initial values of struct for example or values before calling ctor in place to array segment without copying? But what I need use for class objects? class Foo { Bar[] buf; this() { buf = myalloc!Bar( 100 ); // I think it's ok foreach( ref b; buf ) b = new Bar; // but calloc can't initialize class correctly } ~this() { static if( gc_disable ) { foreach( ref b; buf ) delete b; free(buf.ptr); } } } Operator new automatically allocate range in GC-manage memory? If it is whether is possible to change this behavior? It's question relates to emplace too?
I guess you should follow andrei's post about new allocators!
Jun 08 2015
next sibling parent reply "Oleg B" <code.viator gmail.com> writes:
 I guess you should follow andrei's post about new allocators!
Can you get link to this post?
Jun 08 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 8 June 2015 at 12:24:56 UTC, Oleg B wrote:
 I guess you should follow andrei's post about new allocators!
Can you get link to this post?
These are some of his posts: http://forum.dlang.org/thread/mku0n4$s35$1 digitalmars.com http://forum.dlang.org/thread/mkl1eh$1mdl$2 digitalmars.com http://forum.dlang.org/thread/mjig8h$2rgi$1 digitalmars.com http://forum.dlang.org/thread/mjdcep$11ri$1 digitalmars.com http://forum.dlang.org/thread/mj3p2j$2qva$1 digitalmars.com http://forum.dlang.org/thread/mir0lg$2l74$1 digitalmars.com http://forum.dlang.org/thread/min9k8$9r9$1 digitalmars.com
Jun 08 2015
parent reply "Oleg B" <code.viator gmail.com> writes:
On Monday, 8 June 2015 at 13:37:40 UTC, Marc Schütz wrote:
 On Monday, 8 June 2015 at 12:24:56 UTC, Oleg B wrote:
 I guess you should follow andrei's post about new allocators!
Can you get link to this post?
These are some of his posts: http://forum.dlang.org/thread/mku0n4$s35$1 digitalmars.com http://forum.dlang.org/thread/mkl1eh$1mdl$2 digitalmars.com http://forum.dlang.org/thread/mjig8h$2rgi$1 digitalmars.com http://forum.dlang.org/thread/mjdcep$11ri$1 digitalmars.com http://forum.dlang.org/thread/mj3p2j$2qva$1 digitalmars.com http://forum.dlang.org/thread/mir0lg$2l74$1 digitalmars.com http://forum.dlang.org/thread/min9k8$9r9$1 digitalmars.com
Thank! Can you say how long wait (on average) to experimental modules will cease be an experimental and will be part of phobos? At next release or it unknown?
Jun 08 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 8 June 2015 at 20:11:31 UTC, Oleg B wrote:
 On Monday, 8 June 2015 at 13:37:40 UTC, Marc Schütz wrote:
 On Monday, 8 June 2015 at 12:24:56 UTC, Oleg B wrote:
 I guess you should follow andrei's post about new allocators!
Can you get link to this post?
These are some of his posts: http://forum.dlang.org/thread/mku0n4$s35$1 digitalmars.com http://forum.dlang.org/thread/mkl1eh$1mdl$2 digitalmars.com http://forum.dlang.org/thread/mjig8h$2rgi$1 digitalmars.com http://forum.dlang.org/thread/mjdcep$11ri$1 digitalmars.com http://forum.dlang.org/thread/mj3p2j$2qva$1 digitalmars.com http://forum.dlang.org/thread/mir0lg$2l74$1 digitalmars.com http://forum.dlang.org/thread/min9k8$9r9$1 digitalmars.com
Thank! Can you say how long wait (on average) to experimental modules will cease be an experimental and will be part of phobos? At next release or it unknown?
Don't know in general. This one isn't even in Phobos yet, but OTOH it is a feature that's very much in demand, so the process might be sped up. Maybe it could even go directly to std.allocator instead of std.experimental.allocator...
Jun 09 2015
prev sibling parent "Oleg B" <code.viator gmail.com> writes:
 I guess you should follow andrei's post about new allocators!
Did you mean this article http://wiki.dlang.org/Memory_Management#Explicit_Class_Instance_Allocation ?
Jun 08 2015
prev sibling parent "thedeemon" <dlang thedeemon.com> writes:
On Sunday, 7 June 2015 at 10:23:22 UTC, Rikki Cattermole wrote:

 Don't worry about collecting at the end. The OS will clean up 
 the app no matter what.
Actually D runtime will also do a collection before exiting. This is why it shows "Number of collections: 2" above. One triggered manually, one by runtime.
Jun 07 2015
prev sibling parent "Mike" <none none.com> writes:
On Sunday, 7 June 2015 at 10:16:36 UTC, Oleg B wrote:
 Hello. I want to try use D without GC and I'm not sure what I 
 do all right.
You may want to take a look at this Wiki page. It has several patterns managing memory without the GC: http://wiki.dlang.org/Memory_Management Mike
Jun 08 2015