现在我几乎正在做这个:
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。
基本上不安全。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)),
)
}()
}