Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leaks in govpp core #184

Merged
merged 2 commits into from
Jan 23, 2024
Merged

Memory leaks in govpp core #184

merged 2 commits into from
Jan 23, 2024

Conversation

VladoLavor
Copy link
Collaborator

@VladoLavor VladoLavor commented Jan 15, 2024

Fixed memory leaks in GoVPP core stream and request handler.

Edit: the second issue was already addressed in #182

The temporary leak is occurring in the request handler. <-time.After() is not garbage-collected before expiration and shouldn't be used in such a frequently called method.

The second memory leak is permanent, caused by the timer not being closed, causing a slow increase in memory consumption over time.

Performance profile (done on ~1000 API calls using the Stream API):
bug-0
bug-1

With the fix:
bug-fix

@VladoLavor VladoLavor self-assigned this Jan 15, 2024
Comment on lines +265 to +271
replyTimeoutTimer := time.NewTimer(ch.receiveReplyTimeout)
defer replyTimeoutTimer.Stop()
select {
case ch.replyChan <- reply:
return // reply sent ok
case <-time.After(ch.receiveReplyTimeout):
// receiver still not ready
case <-replyTimeoutTimer.C:
// receiver still isn't ready

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the idea but I don't understand the issue.
time.After creates a temporary leak until the timer expires. After the expiration, it is supposed to be garbage collected. By default the timeout is 100ms. So I am not sure how you can fire enough API calls in such a little time window to create a significant memory impact.

Copy link
Collaborator Author

@VladoLavor VladoLavor Jan 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hardeker hello Arthur, two reasons:

  1. the reply timeout is indeed 100ms by default, but is configurable via ReplyChannelTimeout so the garbage collection can be easily and unknowingly by a user "postponed".
  2. It depends on what we consider a "significant memory impact". I understand the impact is temporary, but memory spikes are noticeable as the timer is responsible for >30% of total GoVPP memory consumption. Or even much more, see this example:
    VirtualBox_CodeFoundry_16_01_2024_10_14_36

With the fix, the time.After() drops to ~10kB in the same scenario.

@ondrej-fabry ondrej-fabry merged commit e31967b into master Jan 23, 2024
9 checks passed
@ondrej-fabry ondrej-fabry deleted the memleak-fix branch January 23, 2024 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants