I can't understand why memory is not freed. Memory profile shows that almost all of the memory used by runtime.malg. If I remove range over channel in DoSomeWork everything works fine.
Here of the output of fmt.Println:
Memory Acquired: 4196600
Memory Used : 745192
Memory Acquired: 2651299576
Memory Used : 393923440
Source code:
func DoSomeWork(work chan int) {
for _ = range work {
}
}
func main() {
k := make(chan int)
m := &runtime.MemStats{}
runtime.ReadMemStats(m)
fmt.Println("Memory Acquired: ", m.Sys)
fmt.Println("Memory Used : ", m.Alloc)
wg := new(sync.WaitGroup)
// generate a lot of goroutines that reads from channel
for i:=0;i<1000000;i++ {
wg.Add(1)
go func() {
DoSomeWork(k)
wg.Done()
}()
}
close(k)
wg.Wait()
// make GC
runtime.GC()
// show memory after garbage collector
runtime.ReadMemStats(m)
fmt.Println("Memory Acquired: ", m.Sys)
fmt.Println("Memory Used : ", m.Alloc)
}