Feature #18494

Updated by ko1 (Koichi Sasada) 5 months ago

 This is intended to give Ruby application developers a way to to 
  improve the out-of-the-box experience for end users running 
  tools written in Ruby.    In most cases, end users are not and 
  cannot be expected to know how to tune the GC better than the 
  developers who wrote the Ruby code. 
  This has no extra API footprint, and will silently be a no-op 
  for other Ruby implementations. 
  One potential incompatibility is users doing something like: 
  ENV["RUBY_GC_..."] = "1m" 
  However, the different behavior would be largely innocuous aside from 
  different performance characteristics in the parent process.    Using: 
  system({ "RUBY_GC_..." => "1m" }, ...) 
  ...would restore the previous behavior (and is generally the 
  preferred usage, anyways, to avoid thread-safety issues). 
  RFC since I've only tested this with RUBY_GC_MALLOC_LIMIT and 
  RUBY_GC_MALLOC_LIMIT_MAX, so far.    I've yet to check Ractor 
  interactions since haven't followed Ruby in several years. 
  I made this change to reduce memory use in a single-threaded 
  pipeline+process manager designed for audio playback; but it 
  probably makes sense for many long-running daemons that want 
  to clamp memory use after all code is loaded. 
  Note: I can't create Redmine tickets due to MFA: [ruby-core:105878]. 
  I completely disagree with MFA for Open Source contributions as it's a 
  needless barrier to participation.    Open Source worked fine for decades 
  without MFA.    I show you my code and even explain my changes; but nobody 
  here knows me and nobody ever will.    I don't want nor need anyone to 
  trust me when they can read my code and even ask me to clarify things 
  if needed. 
  hash.c                 | 5 +++++ 
  test/ruby/test_gc.rb | 4 ++++ 
  2 files changed, 9 insertions(+) 
  diff --git a/hash.c b/hash.c 
  index f032ef642a..d7cc797ef5 100644 
  --- a/hash.c 
  +++ b/hash.c 
  @@ -4911,6 +4911,7 @@ static VALUE env_aset(VALUE nm, VALUE val); 
  static void 
  reset_by_modified_env(const char *nam) 
  +      static char gc_var_pfx[] = "RUBY_GC_"; 
   * ENV['TZ'] = nil has a special meaning. 
   * TZ is no longer considered up-to-date and ruby call tzset() as needed. 
  @@ -4919,6 +4920,10 @@ reset_by_modified_env(const char *nam) 
  if (ENVMATCH(nam, TZ_ENV)) { 
  +      } else if (ENVNMATCH(nam, gc_var_pfx, sizeof(gc_var_pfx) - 1)) { 
  +          ENV_LOCK(); 
  +          ruby_gc_set_params(); 
  +          ENV_UNLOCK(); 
  diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb 
  index 788f2974b5..5fd5924fb3 100644 
  --- a/test/ruby/test_gc.rb 
  +++ b/test/ruby/test_gc.rb 
  @@ -334,6 +334,10 @@ def test_gc_parameter 
  assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_OLDMALLOC_LIMIT_MAX=16000000/, "") 
  assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=2.0/, "") 
  +      assert_in_out_err(["-w", "-e", <<-'end'], "", [], /RUBY_GC_MALLOC_LIMIT=1024/, "") 
  +        ENV['RUBY_GC_MALLOC_LIMIT'] = '1k' 
  +      end 
  def test_profiler_enabled