We have a simple websocket service based on go-socket.io 
<https://github.com/googollee/go-socket.io> and have a memory leak problem. 
 We found the memory usage is always increase, the idle heap is not return 
back to the OS. The heap pprof show that the runtime.goexit took much 
memory,  seems  that the memory not release after the goroutine exit. 

1. *heap callgraph*

<https://lh3.googleusercontent.com/-3nI7AU3xVfY/V84l_cR_32I/AAAAAAAAAEw/bzg87TMjlkoLvyCzSkfXuP0l-a5-kNF7wCLcB/s1600/comet_heap.png>




2. *gc debug log*

gc 440 @51045.897s 0%: 0.034+4182+0.96 ms clock, 0.13+0/4182/12246+3.8 ms 
cpu, 4304->4309->4143 MB, 8266 MB goal, 4 P
scvg340: inuse: 4404, idle: 15, sys: 4419, released: 0, consumed: 4419 (MB)
GC forced
gc 441 @51170.096s 0%: 3.7+4355+1.4 ms clock, 14+2.9/4357/12795+5.8 ms cpu, 
4317->4323->4158 MB, 8287 MB goal, 4 P
GC forced
gc 442 @51294.460s 0%: 0.034+3987+1.2 ms clock, 0.13+1.5/3987/11701+4.9 ms 
cpu, 4336->4341->4169 MB, 8316 MB goal, 4 P
scvg341: inuse: 4318, idle: 133, sys: 4451, released: 0, consumed: 4451 (MB)
GC forced
gc 443 @51418.451s 0%: 0.36+3925+0.99 ms clock, 1.4+4.0/3925/11554+3.9 ms 
cpu, 4350->4356->4182 MB, 8338 MB goal, 4 P
scvg342: inuse: 4363, idle: 103, sys: 4466, released: 0, consumed: 4466 (MB)
GC forced
gc 444 @51542.394s 0%: 0.042+3986+1.6 ms clock, 0.16+0/3981/11757+6.5 ms 
cpu, 4361->4367->4194 MB, 8365 MB goal, 4 P
scvg343: inuse: 4404, idle: 74, sys: 4478, released: 0, consumed: 4478 (MB)
GC forced
gc 445 @51666.384s 0%: 3.4+3987+1.4 ms clock, 13+2.5/3986/11747+5.7 ms cpu, 
4375->4382->4208 MB, 8388 MB goal, 4 P
scvg344: inuse: 4454, idle: 39, sys: 4493, released: 0, consumed: 4493 (MB)
GC forced
gc 446 @51790.379s 0%: 0.055+4147+1.5 ms clock, 0.22+0/4139/12125+6.2 ms 
cpu, 4396->4402->4220 MB, 8416 MB goal, 4 P
scvg345: inuse: 4509, idle: 5, sys: 4514, released: 0, consumed: 4514 (MB)
GC forced
gc 447 @51914.542s 0%: 0.052+4205+2.1 ms clock, 0.21+1.5/4199/12348+8.5 ms 
cpu, 4413->4420->4234 MB, 8441 MB goal, 4 P
GC forced
gc 448 @52038.752s 0%: 2.7+4517+1.8 ms clock, 11+2.3/4517/13245+7.2 ms cpu, 
4428->4436->4247 MB, 8469 MB goal, 4 P
scvg346: inuse: 4406, idle: 142, sys: 4548, released: 0, consumed: 4548 (MB)
GC forced
gc 449 @52163.276s 0%: 0.033+4206+1.3 ms clock, 0.13+0/4206/12306+5.3 ms 
cpu, 4442->4449->4259 MB, 8495 MB goal, 4 P
scvg347: inuse: 4452, idle: 109, sys: 4561, released: 0, consumed: 4561 (MB)
GC forced
gc 450 @52287.491s 0%: 0.044+4262+2.0 ms clock, 0.17+0/4261/12565+8.2 ms 
cpu, 4452->4459->4272 MB, 8519 MB goal, 4 P
scvg348: inuse: 4498, idle: 74, sys: 4572, released: 0, consumed: 4572 (MB)
GC forced
gc 451 @52411.769s 0%: 0.028+4012+2.0 ms clock, 0.11+0.066/3992/11762+8.0 
ms cpu, 4471->4477->4285 MB, 8544 MB goal, 4 P
scvg349: inuse: 4550, idle: 40, sys: 4590, released: 0, consumed: 4590 (MB)

*3. example code*
















*       server.On("error", func(so socketio.Socket, err error) {            
    logger := SocketLogger(so)                logger.Error("socket connect 
error")        })        server.On("connection", func(so socketio.Socket) 
{                var (                        uid   string                  
      exist bool                )                logger := 
SocketLogger(so)                claim := (context.Get(so.Request(), 
"user")).(*jwt.Token).Claims                // after get the claims, should 
clear the request context                context.Clear(so.Request())        
        var rawUID interface{}                if user, ok := 
claim.(jwt.MapClaims); ok {                        if rawUID, ok = 
user[setting.JwtUserClaimField]; !ok {                                
logger.Error("invalid user claim")                                
so.Emit("disconnect", "invalid user claim")                        }        
        } else {                        logger.Errorf("invalid jwt claim 
%s", claim)                        so.Emit("disconnect", "invalid user 
claim")                }                if uid, exist = rawUID.(string); 
exist {                        // Multi connection for same user will be 
join to the same room                        so.Join(uid)                  
      // root for broadcast all user                        
so.Join(Hourse)                        c.users.Add(uid, 1)                  
      logger.Debug("socket connected")                        if 
setting.DEBUG {                                so.Emit("debug", 
fmt.Sprintf("Your uid is %s, sid is %s", uid, so.Id()))                    
    }                } else {                        so.Emit("disconnect", 
"invalid user claim")                }                so.On("debug", 
func(data string) {                        log.Debugf("debug data from 
client %s", data)                })                so.On("disconnection", 
func(data string) {                        logger.Debugf("socket 
disconnected")                        c.users.Add(uid, -1)                  
                      })        })*
Problem: 

1. Is this really a memory leak problem? Or just It is  normal  because the 
golang not release the memory back to OS until the OS request more memory?
2. How can I found the problem point?




 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to