Skip to content

Commit

Permalink
[FIXED] Leaking memory on usage of getHash() (#4329)
Browse files Browse the repository at this point in the history
If we created lots of hashes, beyond server names, like for consumer or
stream NRG group names etc, these maps would grow and not release
memory. Performance hit is ~300ns per call, and we can use string intern
trick if need be at a future date since it is GC friendly.

Signed-off-by: Derek Collison <derek@nats.io>

Resolves #4289
  • Loading branch information
derekcollison committed Jul 20, 2023
2 parents da60f2a + b68aed9 commit ba517e4
Showing 1 changed file with 7 additions and 27 deletions.
34 changes: 7 additions & 27 deletions server/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,35 +843,15 @@ func getHash(name string) string {
return getHashSize(name, sysHashLen)
}

var nameToHashSize8 = sync.Map{}
var nameToHashSize6 = sync.Map{}

// Computes a hash for the given `name`. The result will be `size` characters long.
func getHashSize(name string, size int) string {
compute := func() string {
sha := sha256.New()
sha.Write([]byte(name))
b := sha.Sum(nil)
for i := 0; i < size; i++ {
b[i] = digits[int(b[i]%base)]
}
return string(b[:size])
}
var m *sync.Map
switch size {
case 8:
m = &nameToHashSize8
case 6:
m = &nameToHashSize6
default:
return compute()
}
if v, ok := m.Load(name); ok {
return v.(string)
}
h := compute()
m.Store(name, h)
return h
sha := sha256.New()
sha.Write([]byte(name))
b := sha.Sum(nil)
for i := 0; i < size; i++ {
b[i] = digits[int(b[i]%base)]
}
return string(b[:size])
}

// Returns the node name for this server which is a hash of the server name.
Expand Down

0 comments on commit ba517e4

Please sign in to comment.