[Issue 1326] New: Garbage Collector dysfunction - Memory leak in gc_term() with DLLs - and more.

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Jul 9 15:48:49 PDT 2007


http://d.puremagic.com/issues/show_bug.cgi?id=1326

           Summary: Garbage Collector dysfunction  - Memory leak in
                    gc_term()  with DLLs - and more.
           Product: D
           Version: 2.002
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: patch
          Severity: critical
          Priority: P2
         Component: Phobos
        AssignedTo: bugzilla at digitalmars.com
        ReportedBy: wqeqweuqy at hotmail.com


--- 1: Memory leak in gc_term() ---

src/phobos/internal/gc/gc.gc_term() is missing a call to _gc.Dtor(). 

Without it, unloading a DLL doesn't release heap pages created by gc_init();
resulting in ~1.5MB being leaked each time a DLL is reloaded.

Adding the _gc.Dtor() call to gc_term(), and rebuilding phobos seemed to solve
the problem, but there may be more resources being leaked. The memory usage for
a process still grows ~100k each time a dll is loaded+unloaded (better than
before at least heh).

Its possible this has to do with the std.thread.Thread.thread_init() call in
gc_init; or something specific to my DLL - in anycase, it's something to
consider.


--- 2: setGCHandle / endGCHandle ---

Calling setGCHandle() for a new DLL *without* manually calling
std.thread.Thread.thread_init() causes newly created threads to crash. I dont
think ive seen this documented anywhere. Also, endGCHandle() seems to fail at
releasing memory associated with the DLL its called from. fullCollect() ends up
referring to memory inside the unmapped DLL later on and seg-faulting. (The
test case here has the GC running in its own DLL)


--- 3: COM objects are being allocated on the GC heap ---

class display : ComObject, public IDirect3D8 {}; 

Gets allocated on the GC heap. fullCollect() causes the program using it to
seg-fault right away.

The test in gc.d/_d_newclass() probably fails:

    if (ci.flags & 1){} // if COM object

Manually allocating the object like this, or by overloading new/delete, causes
it to function properly:

    ClassInfo info;

    void *obj = c_alloc(info.init.length);
    (cast(byte*)obj)[0 .. info.init.length] = info.init[];


-- 



More information about the Digitalmars-d-bugs mailing list