From: "mood_vuadensl (LOIC VUADENS) via ruby-core" Date: 2025-04-02T16:18:42+00:00 Subject: [ruby-core:121520] [Ruby Bug#21214] VmRSS consumption increase in Ruby 3.4.2 vs Ruby 3.3.6 Issue #21214 has been updated by mood_vuadensl (LOIC VUADENS). Description updated Add random strings to the object created during the loop ---------------------------------------- Bug #21214: VmRSS consumption increase in Ruby 3.4.2 vs Ruby 3.3.6 https://bugs.ruby-lang.org/issues/21214#change-112544 * Author: mood_vuadensl (LOIC VUADENS) * Status: Open * ruby -v: ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Hello, After updating Ruby from 3.3.6 to 3.4.2, our batch-style (not based on rails) application exceed its memory limit. Below is an example script that runs on both versions and demonstrates that 'ObjectSpace.memsize_of_all' does not vary significantly, but the OS 'VmRSS' increases significantly. Do you have any information on what might have caused this increase or any lead to reduce this peak? Here is the result on a Linux 5.15.167.4-microsoft-standard-WSL2: with Ruby 3.3.6: ```text ruby 3.3.6 (2024-11-05 revision 75015d4c1f) [x86_64-linux] On start on 3.3.6 - OS VmRSS: 20616 kB - ObjectSpace.memsize_of_all: 1.7MB On first full workload: 0 - OS VmRSS: 559212 kB - ObjectSpace.memsize_of_all: 327.86MB .... After workload - OS VmRSS: 711776 kB - ObjectSpace.memsize_of_all: 327.86MB After data released - OS VmRSS: 616364 kB - ObjectSpace.memsize_of_all: 1.71MB ``` and 3.4.2: ```text ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-linux] On start on 3.4.2 - OS VmRSS: 13076 kB - ObjectSpace.memsize_of_all: 1.7MB On first full workload: 0 - OS VmRSS: 674324 kB - ObjectSpace.memsize_of_all: 353.6MB .... After workload - OS VmRSS: 1000628 kB - ObjectSpace.memsize_of_all: 327.85MB After data released - OS VmRSS: 843636 kB - ObjectSpace.memsize_of_all: 1.7MB ``` and the associated script: ```ruby require 'objspace' BYTES_TO_MB = 1024 * 1024 $stdout.sync = true srand(1) # Declare supporting code def print_info(context) puts context GC.start os_mem_metric = File.readlines("/proc/#{Process.pid}/status").find { |line| line.start_with?('VmRSS:') } puts "- OS #{os_mem_metric}" puts "- ObjectSpace.memsize_of_all: #{(ObjectSpace.memsize_of_all.to_f/BYTES_TO_MB).round(2)}MB" puts '' end def random_string = Array.new(10) { rand(99) }.join class A def initialize @a = random_string @b = rand(1000000000000) end end # Main print_info "On start on #{RUBY_VERSION}" objects = Array.new(1_000_000) { A.new } hashes = Array.new(250_000) { { a: rand(100_000), b: rand(100_000), c: random_string } } arrays = Array.new(250_000) { [rand(100_000), rand(100_000), random_string] } keep_if = ->(index) { index.even? } 0.upto(3) do |i_loop| objects = objects.map.with_index { |obj, index| keep_if.call(index) ? obj : A.new } hashes = hashes.map.with_index { |obj, index| keep_if.call(index) ? obj : { a: rand(10_000), b: rand(10_000), c: random_string } } arrays = arrays.map.with_index { |obj, index| keep_if.call(index) ? obj : [rand(10_000), rand(10_000), random_string] } print_info " On first full workload: #{i_loop}" if i_loop.zero? keep_if = ->(index) { index.odd? } if i_loop == 1 keep_if = ->(index) { index%5 == 0 } if i_loop == 2 keep_if = ->(index) { index.even? } if i_loop == 3 print '.' end puts '' print_info 'After workload' objects.clear hashes.clear arrays.clear print_info 'After data released' ``` Regards -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/