Golang memory leak issues and treatment methods

1, to beat the system pressure, increased memory footprint, but after the cessation of pressure, memory can not be reduced, it may have a memory leak.
2, top does not reflect real-time programs take up memory, because Go application to the system memory is not used, the system does not immediately returned.
3, the program uses system memory, Go heap memory, the actual use of memory: the application memory from the system memory pool will be managed in Go, the entire memory pages, is not accessed for a long time and meet certain conditions, only to be returned to operation system. And because there are GC, heap memory can not represent memory footprint, and the rest later cleared, it is the actual use of memory.
4. Go call runtime.ReadMemStats can see the memory usage information
5, using the go tool pprof -inuse_space http://127.0.0.1:6060/debug/pprof/heap?debug=2 get more detailed information, which is the actual HeapInuse memory usage

6, the first principle is that absolutely can not be closed by the consumer channel, because data is written to panic closed channel. Correct posture is finished after all the data producer, closed channel, the consumer is responsible for the consumption of all finished inside the data channel

Produce FUNC (CH Chan <- T) { 
    the defer Close (CH) // Manufacturer data written Close Channel 
    CH <- T {} 
} 
FUNC Consume (CH <- Chan T) {
     for _ Range CH = { // consumption All the data which are read-Range for 
    } 
} 
CH: = the make (Chan T) 
Go Produce (CH) 
Consume (CH)

 

7, the second principle is to use the broadcast channel off cancellation action can be used with the class WaitGroup

Produce FUNC (CH Chan <- T, Chan cancel struct {}) {
     select {
       Case CH <- T {}:
       Case <- cancel: // Use select cancel operation while monitoring 
    } 
} 
FUNC Consume (CH <-chan T, Chan Cancel struct {}) { 
    V: = <- CH 
    ERR: = doSomething (V)
     IF ERR =! nil { 
        Close (Cancel) // able to inform all produce exit 
        return 
    } 
} 
for I: = 0 ; I < 10 ; ++ I {
    go produce()
}
consume()

 

8, to close the coroutine signaled by chann

FUNC (m * TtlMap) Clear () {
     for {
         SELECT {
         // Close 
        Case <- m.stop:
             return 

        // regular cleaning ... 
        } 
    } 
}


9, when MapWarpper as a local variable that defines the end of its functions, MapWarpper life cycle has ended, Gc will be recovered. Gc executed when the recovery MapWarpper onGarbageCollect () function, the clear Ttlmap coroutine off, turn Ttlmap recovered.

{TtlMap strcut 
    ... 
    STOP Chan BOOL 
} 

// package defined 
struct MapWarpper {
     * TtlMap 
} 

FUNC New () * MapWarpper { 
    Map: = & TtlMap { 
        ... 
    } 
    Go map.clear () 

    // coated with a layer 
    mw: & = MapWarpper Map {} 
    
    // key here: when the setting operation is recovered 
    runtime.SetFinalizer (Mw of, onGarbageCollect)
     return Mw of 
}

 

10, the packet context to avoid memory leaks

func main() {
    ctx, cancel := context.WithCancel(context.Background())
 
    ch := func(ctx context.Context) <-chan int {
        ch := make(chan int)
        go func() {
            for i := 0; ; i++ {
                select {
                case <- ctx.Done():
                    return
                case ch <- i:
                }
            }
        } ()
        return ch
    }(ctx)
 
    for v := range ch {
        fmt.Println(v)
        if v == 5 {
            cancel()
            break
        }
    }
}

 

Guess you like

Origin www.cnblogs.com/share-ideas/p/11365511.html