Jump to page: 1 2
Thread overview
using D without GC
Jun 07, 2015
Oleg B
Jun 07, 2015
Rikki Cattermole
Jun 07, 2015
Oleg B
Jun 08, 2015
Alex Parrill
Jun 08, 2015
Andrea Fontana
Jun 08, 2015
Oleg B
Jun 08, 2015
Marc Schütz
Jun 08, 2015
Oleg B
Jun 09, 2015
Marc Schütz
Jun 08, 2015
Oleg B
Jun 08, 2015
thedeemon
Jun 08, 2015
Mike
June 07, 2015
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?
June 07, 2015
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.
June 07, 2015
> 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?
June 08, 2015
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)]
June 08, 2015
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.
June 08, 2015
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
June 08, 2015
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!


June 08, 2015
> I guess you should follow andrei's post about new allocators!

Can you get link to this post?

June 08, 2015
> 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 ?
June 08, 2015
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
« First   ‹ Prev
1 2