1

I wrote a simple http golang webserver to test the Go garbage collection (releasing memory of inaccessible pointers), But in strees testing ,I understand it consumes excessive ram.

According to some question/answers, I found out Golang does garbage collection automatically, manage the extra memory itself and doesn't get back memory to OS at once. Some results:

  • The webserver release ram after about 5mins.

  • The webserver consumes ram until it gets up to specific level and requesting more connections not gets more memory(about 4GB in my case)

Consuming 4GB of ram isn't cool! So i added a Goroutine to my code that gets the extra memory back to OS.

The code:

type t struct{
    a       []string
    b       map[string]string
}
var x t = t{
    a:  []string{"1","2"},
    b:  make(map[string]string),
}

func handler(w http.ResponseWriter, r *http.Request) {
    x := &t{}
    fmt.Fprintf(w, "pong", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/ping", handler)
    go func(){
        for {
            time.Sleep(10 * time.Second)
            fmt.Println("Free up memory...")
            debug.FreeOSMemory() 
        }

    }()
    log.Fatal(http.ListenAndServe(":8080", nil))
}

For stress testing i use Apache Bench:

ab -c 100 -n 400000 http://127.0.0.1:8080/ping

I ran above command about 10 times continuously to check the ram usage. It works very well, But the problem is, Is there any standard way that Go releases the memory better!?

I know in some cases, it's good that Go manages the memory itself instead of repetitive releasing and getting back memory from OS, But in my case, 5 minutes delay is very much to releasing memory.

hadi2f244
  • 19
  • 1
  • 4
  • On which operating system, and which implementation and version of Go? Details matter a lot, so please **edit your question** to give more of them (and motivation and context). – Basile Starynkevitch Apr 22 '18 at 07:17
  • BTW, on most OSes, a Go process consumes [virtual memory](https://en.wikipedia.org/wiki/Virtual_memory) (in its virtual address space), not RAM. The RAM proper is managed by the OS kernel, not by the Go program or runtime. Also, it could be the case that releasing memory too early would decrease performance – Basile Starynkevitch Apr 22 '18 at 07:18

1 Answers1

7

You might want to call FreeOSMemory from runtime/debug

But you probably should not. Try instead to tune the GC for your particular application and usage (perhaps using SetGCPercent). It is likely that using FreeOSMemory too often would decrease performance, so be sure to benchmark.

Notice that the garbage collection implementation has improved in recent versions of Go, and is different in various Go implementations (e.g. in GCC Go).

Don't confuse RAM usage (the RAM is managed by your OS kernel, not by your Go process), virtual memory, virtual address space. Read about RSS, demand paging, thrashing.

For an overview of garbage collection techniques, read The GC Handbook.

For a better understanding of OSes, read Operating Systems: Three Easy Pieces

See also Linux ate my RAM.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547