Issue #19122 has been updated by smcgivern (Sean McGivern).
ioquatix (Samuel Williams) wrote in #note-2:
I don't have a strong opinion about this, but
I'm generally against loosing performance.
Maybe it can be controlled using environment variable.
Having this user-controllable works for me, although I don't know about the Ruby
project's general stance on toggles like this.
@ioquatix is
https://github.com/socketry/falcon-benchmark the right test suite to run
here? I'm not sure if that's what you ran in
https://bugs.ruby-lang.org/issues/15997#note-19, or if that was slightly different.
I'm happy to try this out with the various options here to quantify the current state
- just point me in the right direction :-)
----------------------------------------
Misc #19122: Use MADV_DONTNEED instead of MADV_FREE when freeing a Fiber's stack
https://bugs.ruby-lang.org/issues/19122#change-100257
* Author: smcgivern (Sean McGivern)
* Status: Open
* Priority: Normal
* Assignee: ioquatix (Samuel Williams)
----------------------------------------
I'd like to propose that Ruby stops using MADV_FREE when freeing a Fiber's stack,
and switches to using MADV_DONTNEED even when MADV_FREE is supported.
MADV_FREE is used in one place in the Ruby codebase, when freeing the stack of a freed
Fiber:
https://git.ruby-lang.org/ruby.git/tree/cont.c#n683
The comment for `fiber_pool_stack_free` says:
```c
// We advise the operating system that the stack memory pages are no longer being used.
// This introduce some performance overhead but allows system to relaim memory when there
is pressure.
```
Where possible (i.e. on Linux 4.5 and later), `fiber_pool_stack_free` uses `MADV_FREE`
over `MADV_DONTNEED`. This has the side effect that memory statistics such as RSS will not
reduce until and unless the OS actually reclaims that memory. If that doesn't happen,
then the reported memory usage via RSS will be much higher than the 'real' memory
usage.
If this was pervasive throughtout the Ruby codebase then that would be one thing, but
currently this is just for Fiber. This means that:
1. A program that doesn't use Fiber will have somewhat reliable RSS statistics on
recent Linux.
2. A program that heavily uses Fiber (such as something using Async::HTTP) will see an
inflated RSS statistic.
Go made a similar change to the one I'm proposing here for similar reasons:
https://github.com/golang/go/issues/42330
While `MADV_FREE` is somewhat faster than
`MADV_DONTNEED`, it doesn't affect many of the statistics that `MADV_DONTNEED` does
until the memory is actually reclaimed. This generally leads to poor user experience, like
confusing stats in `top` and other monitoring tools; and bad integration with management
systems that respond to memory usage.
[...]
I propose we change the default to prefer `MADV_DONTNEED` over `MADV_FREE`, to favor
user-friendliness and minimal surprise over performance. I think it's become clear
that Linux's implementation of `MADV_FREE` ultimately doesn't meet our needs.
As an aside, MADV_FREE was not used in Ruby 3.1 (
https://bugs.ruby-lang.org/issues/19101),
and I haven't found any bugs filed about this behaviour other than that one.
--
https://bugs.ruby-lang.org/