current GC behavior

luka8088 luka8088 at owave.net
Tue Nov 6 03:27:27 PST 2012


Hello everyone,

I was writing some unit tests and I also wanted to test that in certain 
cases object references are properly removed everywhere so that GC can 
collect them in order to make sure there is no memory leak. While trying 
to achieve this I learned that objects are not always collected at the 
time I would expect them to, so I documented current behavior and some tips.


/**
  * Compiled with:
  *   DMD32 D Compiler v2.060
  *   Copyright (c) 1999-2012 by Digital Mars written by Walter Bright
  *   Documentation: http://www.dlang.org/index.html
  */

module program;

import std.stdio;
import std.string;
import core.memory;

void main () {

   writeln("// ---------- beginning of main");

   mixin(writeAndExec(4, q{

     GC.collect();
     new a("a1");
     // GC will collect a1
     GC.collect();

     auto a2 = new a("a2");
     // GC will collect a2 because a2 will not be used in the future
     GC.collect();

     auto a3 = new a("a3");
     // GC will not collect a3 because a3 will be used in the future
     // tip: make some interaction with the object if you don't want
     // it to get collected before the end of scope GC.collect();
     GC.collect();
     a3.i = 1;

     {
       auto a4 = new a("a4");
       // GC will collect a4 because a4 will not be used in the future
       GC.collect();
     }

     {
       auto a5 = new a("a5");
       a5.i = 1;
       // maybe GC could collect a5 because a5 will be used
       // in the future, but it has been used and for some
       // (probably implementation) reasons GC does not collect it
       GC.collect();
     }

     ({
       auto a6 = new a("a6");
       a6.i = 1;
       // same as previous GC.collect (for a5)
       GC.collect();
     })();

     // maybe GC could collect a5 because a5 has gone out of scope
     // but for some (probably implementation) reasons GC does not
     // collect it, however, it will collect a6 that was declared
     // and used in a function call
     // tip: use function call (like a6 case) for a scope if you
     // want GC.collect(); to collect objects declared inside it
     GC.collect();

   }));

   writeln("// ---------- end of main");

}

class a {

   string id;
   int i;

   this (string id) {
     this.id = id;
     writeln("// ! ", this.id, " is now constructed");
   }

   ~this () {
     writeln("// ! ", this.id, " is now destructed");
   }

}

string writeAndExec (uint ident, string code) {
   string result = "";
   foreach (line; code.splitLines())
     result ~= "writeln(`" ~ line[line.length > ident ? ident : 0 .. $] 
~ "`);\n" ~ line ~ "\n";
   return result;
}




More information about the Digitalmars-d-learn mailing list