Skip to content

Instantly share code, notes, and snippets.

@LesnyRumcajs
Last active July 10, 2025 15:33
Show Gist options
  • Select an option

  • Save LesnyRumcajs/711b5c5c8b0e5439febc6201b0d84b09 to your computer and use it in GitHub Desktop.

Select an option

Save LesnyRumcajs/711b5c5c8b0e5439febc6201b0d84b09 to your computer and use it in GitHub Desktop.
Top File-Backed Memory Mappings (Ruby script)
#!/usr/bin/env ruby
require 'optparse'
def parse_smaps(pid)
smaps_path = "/proc/#{pid}/smaps"
unless File.exist?(smaps_path)
abort("Error: #{smaps_path} not found. Are you root?")
end
data = Hash.new { |h, k| h[k] = { 'Rss' => 0, 'Shared_Clean' => 0, 'Private_Clean' => 0 } }
current_mapping = nil
File.foreach(smaps_path) do |line|
if line =~ /^([0-9a-f]+)-([0-9a-f]+)\s.*\s(\/.+)$/
current_mapping = $3
elsif line =~ /^(Rss|Shared_Clean|Private_Clean):\s+(\d+) kB/
key, value = $1, $2.to_i
data[current_mapping][key] += value if current_mapping
end
end
data
end
def print_top_mappings(data, limit)
sorted = data.sort_by { |_, mem| -(mem['Shared_Clean'] + mem['Private_Clean']) }
total_clean_kb = 0
total_rss_kb = 0
puts "\nTop #{limit} file-backed memory mappings (by cached memory):"
puts format("%12s %10s %s", "Memory (MB)", "Rss (MB)", "Mapping Path")
puts "-" * 60
sorted.first(limit).each do |path, mem|
clean_kb = mem['Shared_Clean'] + mem['Private_Clean']
rss_kb = mem['Rss']
total_clean_kb += clean_kb
total_rss_kb += rss_kb
puts format("%12.1f %10.1f %s", clean_kb / 1024.0, rss_kb / 1024.0, path)
end
puts "-" * 60
puts format("%12.1f %10.1f TOTAL (Top #{limit})", total_clean_kb / 1024.0, total_rss_kb / 1024.0)
end
if ARGV.length < 1
puts "Usage: ruby cached_mappings.rb <pid> [top_n]"
exit 1
end
pid = ARGV[0]
top_n = (ARGV[1] || 10).to_i
mem_data = parse_smaps(pid)
print_top_mappings(mem_data, top_n)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment