如何监控golang websocket服务器内存泄漏

问题描述 投票:0回答:1

现在我几乎正在做这个:

    import (
      "unsafe"
    )
    
    func (s *Service)  logStats(){
      go func(){
    
        for {
    
           time.Sleep(50*time.Second);
    

           vbl.Stdout.Debug(
                vbl.Id("f30bb768-280a-4bbf-9c17-2b7214e91c69"),
                fmt.Sprintf("topicIdToRMQChannels:%v/%v,", len(s.topicIdToRMQChannels), unsafe.Sizeof(s.topicIdToRMQChannels)),
                fmt.Sprintf("conversationIdToConns:%v/%v,", len(s.conversationIdToConns), unsafe.Sizeof(s.conversationIdToConns)),
                fmt.Sprintf("clientIdToConns:%v/%v,", len(s.clientIdToConns), unsafe.Sizeof(s.clientIdToConns)),
                fmt.Sprintf("userIdToConvId:%v/%v,", len(s.userIdToConvId), unsafe.Sizeof(s.userIdToConvId)),
                fmt.Sprintf("convIdToUserIds:%v/%v", len(s.convIdToUserIds), unsafe.Sizeof(s.convIdToUserIds)),
                fmt.Sprintf("redisMap:%v/%v,", len(s.redisMap.IdMap), unsafe.Sizeof(s.redisMap.IdMap)),
                fmt.Sprintf("rabbitMap:%v/%v,", len(s.rabbitMap.IdMap), unsafe.Sizeof(s.rabbitMap.IdMap)),
                fmt.Sprintf("kafkaMap:%v/%v", len(s.kafkaMap.IdMap), unsafe.Sizeof(s.kafkaMap.IdMap)),
            )
    
        }
    
    }()
  }

上面记录了几乎所有在服务器生命周期内可能意外变得太大的数据结构。

有没有更好的方法来监控内存使用情况?

unsafe.Sizof()
调用似乎总是返回 8。

go memory memory-management memory-leaks heap-memory
1个回答
-2
投票

基本上不安全。SizeOf没有价值,所以你必须根据自己的设计来计算尺寸,我就是这样做的:

func calculateGenericMapSize[T comparable, K any](m map[T]K) []int {
    // calculate size (memory) of map
    totalKeyLength := len(m)
    totalValueLength := 0

    for _, v := range m {

        val := reflect.ValueOf(v)

        // If v is a pointer, find the value it points to
        if val.Kind() == reflect.Ptr && !val.IsNil() {
            val = val.Elem()
        }

        switch val.Kind() {
        case reflect.Map, reflect.Slice, reflect.Array:
            totalValueLength += val.Len()
        default:
            totalValueLength += 1
        }
    }

    return []int{totalKeyLength, totalValueLength}
}

func calculateMapSize[T comparable, K comparable, Z any](m map[T]map[K]Z) []int {
    totalKeyLength := len(m)
    totalValueLength := 0

    for _, innerMap := range m {
        totalValueLength += len(innerMap)
    }

    return []int{totalKeyLength, totalValueLength}
}

func (s *Service) logMemoryStats() {

    go func() {


            vbl.Stdout.Debug(
                vbl.Id("f30bb768-280a-4bbf-9c17-2b7214e91c69"),
                fmt.Sprintf("topicIdToRMQChannels:%v", calculateMapSize(s.topicIdToRMQChannels)),
                fmt.Sprintf("conversationIdToConns:%v,", calculateMapSize(s.conversationIdToConns)),
                fmt.Sprintf("clientIdToConns:%v,", calculateMapSize(s.clientIdToConns)),
                fmt.Sprintf("userIdToConvId:%v,", calculateMapSize(s.userIdToConvId)),
                fmt.Sprintf("convIdToUserIds:%v", calculateMapSize(s.convIdToUserIds)),
                fmt.Sprintf("redisMap:%v,", calculateGenericMapSize(s.redisMap.IdMap)),
                fmt.Sprintf("rabbitMap:%v,", calculateGenericMapSize(s.rabbitMap.IdMap)),
                fmt.Sprintf("kafkaMap:%v", calculateGenericMapSize(s.kafkaMap.IdMap)),
            )


    }()

}
© www.soinside.com 2019 - 2024. All rights reserved.