Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2440 from rainers/gc_cleanup
Browse files Browse the repository at this point in the history
GC cleanup can now be configured as a DRT GC option
  • Loading branch information
thewilsonator authored Jan 9, 2019
2 parents 82fee29 + 58b1e1f commit 9e68f65
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 12 deletions.
26 changes: 26 additions & 0 deletions changelog/gc_cleanup.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
GC cleanup can now be configured as a DRT GC option

The default cleanup method for the GC is to unconditionally run a
collection before runtime termination to finalize objects
that are still alive and hold resources that affect system state outside
the current process. This combines the worst of possible alternatives:
it can cause a considerable delay and does not guarantee finalization
of all objects as roots might still exist.

The cleanup behaviour can now be configured by a DRT option to the
$(LINK2 $(ROOT_DIR)spec/garbage.html, GC configuration),
e.g. by passing `--DRT-gcopt=cleanup:none` on the command
line. Three options are provided:

$(UL
$(LI collect: run a collection (the default for backward compatibility))
$(LI none: do nothing)
$(LI finalize: all live objects are finalized unconditionally)
)

As usual, you can also embed the configuration into the application by
redefining `rt_options`, e.g.

-------
extern(C) __gshared string[] rt_options = [ "gcopt=cleanup:none" ];
-------
2 changes: 2 additions & 0 deletions src/gc/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct Config
size_t maxPoolSize = 64; // maximum pool size (MB)
size_t incPoolSize = 3; // pool size increment (MB)
float heapSizeFactor = 2.0; // heap size to used memory ratio
string cleanup = "collect"; // select gc cleanup method none|collect|finalize

@nogc nothrow:

Expand All @@ -43,6 +44,7 @@ struct Config
maxPoolSize:N - maximum pool size in MB (%lld)
incPoolSize:N - pool size increment MB (%lld)
heapSizeFactor:N - targeted heap size to used memory ratio (%g)
cleanup:none|collect|finalize - how to treat live objects when terminating (collect)
";
printf(s.ptr, disable, profile, cast(long)initReserve, cast(long)minPoolSize,
cast(long)maxPoolSize, cast(long)incPoolSize, heapSizeFactor);
Expand Down
39 changes: 27 additions & 12 deletions src/gc/proxy.d
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,35 @@ extern (C)

void gc_term()
{
// NOTE: There may be daemons threads still running when this routine is
// called. If so, cleaning memory out from under then is a good
// way to make them crash horribly. This probably doesn't matter
// much since the app is supposed to be shutting down anyway, but
// I'm disabling cleanup for now until I can think about it some
// more.
//
// NOTE: Due to popular demand, this has been re-enabled. It still has
// the problems mentioned above though, so I guess we'll see.

if (isInstanceInit)
{
instance.collectNoStack(); // not really a 'collect all' -- still scans
// static data area, roots, and ranges.
switch (config.cleanup)
{
default:
import core.stdc.stdio : fprintf, stderr;
fprintf(stderr, "Unknown GC cleanup method, please recheck ('%.*s').\n",
cast(int)config.cleanup.length, config.cleanup.ptr);
break;
case "none":
break;
case "collect":
// NOTE: There may be daemons threads still running when this routine is
// called. If so, cleaning memory out from under then is a good
// way to make them crash horribly. This probably doesn't matter
// much since the app is supposed to be shutting down anyway, but
// I'm disabling cleanup for now until I can think about it some
// more.
//
// NOTE: Due to popular demand, this has been re-enabled. It still has
// the problems mentioned above though, so I guess we'll see.

instance.collectNoStack(); // not really a 'collect all' -- still scans
// static data area, roots, and ranges.
break;
case "finalize":
instance.runFinalizers((cast(ubyte*)null)[0 .. size_t.max]);
break;
}

ManualGC.finalize(instance);
ConservativeGC.finalize(instance);
Expand Down

0 comments on commit 9e68f65

Please sign in to comment.