Skip to content

Commit

Permalink
runtime: fix freeOSMemory to free memory immediately
Browse files Browse the repository at this point in the history
Currently freeOSMemory makes only marking phase of GC, but not sweeping phase.
So recently memory is not released after freeOSMemory.
Do both marking and sweeping during freeOSMemory.
Fixes #8019.

LGTM=khr
R=golang-codereviews, khr
CC=golang-codereviews, rsc
https://golang.org/cl/97550043
  • Loading branch information
dvyukov committed May 19, 2014
1 parent d021d98 commit e893acf
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 13 deletions.
11 changes: 1 addition & 10 deletions src/pkg/runtime/malloc.goc
Expand Up @@ -849,16 +849,7 @@ runtime·cnewarray(Type *typ, intgo n)
}

func GC() {
// We assume that the user expects unused memory to have
// been freed when GC returns. To ensure this, run gc(1) twice.
// The first will do a collection, and the second will force the
// first's sweeping to finish before doing a second collection.
// The second collection is overkill, but we assume the user
// has a good reason for calling runtime.GC and can stand the
// expense. At the least, this fixes all the calls to runtime.GC in
// tests that expect finalizers to start running when GC returns.
runtime·gc(1);
runtime·gc(1);
runtime·gc(2); // force GC and do eager sweep
}

func SetFinalizer(obj Eface, finalizer Eface) {
Expand Down
8 changes: 6 additions & 2 deletions src/pkg/runtime/mgc0.c
Expand Up @@ -2239,6 +2239,7 @@ runtime·updatememstats(GCStats *stats)
struct gc_args
{
int64 start_time; // start time of GC in ns (just before stoptheworld)
bool eagersweep;
};

static void gc(struct gc_args *args);
Expand All @@ -2257,6 +2258,8 @@ readgogc(void)
return runtime·atoi(p);
}

// force = 1 - do GC regardless of current heap usage
// force = 2 - go GC and eager sweep
void
runtime·gc(int32 force)
{
Expand Down Expand Up @@ -2292,7 +2295,7 @@ runtime·gc(int32 force)
return;

runtime·semacquire(&runtime·worldsema, false);
if(!force && mstats.heap_alloc < mstats.next_gc) {
if(force==0 && mstats.heap_alloc < mstats.next_gc) {
// typically threads which lost the race to grab
// worldsema exit here when gc is done.
runtime·semrelease(&runtime·worldsema);
Expand All @@ -2301,6 +2304,7 @@ runtime·gc(int32 force)

// Ok, we're doing it! Stop everybody else
a.start_time = runtime·nanotime();
a.eagersweep = force >= 2;
m->gcing = 1;
runtime·stoptheworld();

Expand Down Expand Up @@ -2490,7 +2494,7 @@ gc(struct gc_args *args)
sweep.spanidx = 0;

// Temporary disable concurrent sweep, because we see failures on builders.
if(ConcurrentSweep) {
if(ConcurrentSweep && !args->eagersweep) {
runtime·lock(&gclock);
if(sweep.g == nil)
sweep.g = runtime·newproc1(&bgsweepv, nil, 0, 0, runtime·gc);
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/runtime/mheap.c
Expand Up @@ -555,7 +555,7 @@ runtime·MHeap_Scavenger(void)
void
runtimedebug·freeOSMemory(void)
{
runtime·gc(1);
runtime·gc(2); // force GC and do eager sweep
runtime·lock(&runtime·mheap);
scavenge(-1, ~(uintptr)0, 0);
runtime·unlock(&runtime·mheap);
Expand Down

0 comments on commit e893acf

Please sign in to comment.