Project

General

Profile

Feature #22186 » str_subseq_memory.rb

himura467 (Akito Shitara), 07/09/2026 03:52 AM

 
#!/usr/bin/env ruby
# Memory impact of retaining many String#byteslice results, for
# https://bugs.ruby-lang.org/issues/22186.
#
# Usage: ruby misc/str_subseq_memory.rb [SIZE...]

require "objspace"

SIZES = ARGV.empty? ? [10, 50, 100, 250, 500, 999, 1000] : ARGV.map { |a| Integer(a) }
N = 200_000

SRC = ("0123456789abcdef" * 128).freeze

def rss_kb
`ps -o rss= -p #{Process.pid}`.to_i
end

puts RUBY_DESCRIPTION
printf("%6s %11s %11s %13s %s\n", "size", "per-slice", "total", "RSS delta", "flags")

SIZES.each do |size|
beg = SRC.bytesize - size
r, w = IO.pipe
fork do
r.close
GC.start
before_mem = ObjectSpace.memsize_of_all(String)
before_rss = rss_kb
slices = Array.new(N) { SRC.byteslice(beg, size) }
GC.start
total = ObjectSpace.memsize_of_all(String) - before_mem
rss = rss_kb - before_rss
dump = ObjectSpace.dump(slices.first)
flags = %w[embedded shared].select { |f| dump.include?("\"#{f}\":true") }.join(",")
w.puts [ObjectSpace.memsize_of(slices.first), total, rss, flags].join(" ")
slices.clear
end
w.close
per, total, rss, flags = r.read.split
Process.wait
printf("%6d %10dB %9.1fMB %11.1fMB %s\n",
size, per, total.to_i / 1024.0 / 1024, rss.to_i / 1024.0, flags || "(heap copy)")
end
(5-5/5)