Class: Process::Metrics::Memory::Linux
- Inherits:
-
Object
- Object
- Process::Metrics::Memory::Linux
- Defined in:
- lib/process/metrics/memory/linux.rb
Overview
Linux implementation of per-process memory metrics using /proc/[pid]/smaps or /proc/[pid]/smaps_rollup, and /proc/[pid]/stat for fault counters. Prefers smaps_rollup when readable (single summary); otherwise falls back to full smaps and counts maps from /proc/[pid]/maps.
Constant Summary collapse
- SMAP =
Mapping from smaps/smaps_rollup line names to Memory struct members (values in kB, converted to bytes when parsing).
{ "Rss" => :resident_size, "Pss" => :proportional_size, "Shared_Clean" => :shared_clean_size, "Shared_Dirty" => :shared_dirty_size, "Private_Clean" => :private_clean_size, "Private_Dirty" => :private_dirty_size, "Referenced" => :referenced_size, "Anonymous" => :anonymous_size, "Swap" => :swap_size, "SwapPss" => :proportional_swap_size, }
Class Method Summary collapse
-
.capture(pid, faults: true, **options) ⇒ Object
Capture memory usage from /proc/[pid]/smaps (and map count from VmFlags) and /proc/[pid]/maps.
-
.capture_faults(pid, usage) ⇒ Object
Extract minor and major page fault counters from
/proc/[pid]/stat(proc(5): fields 10=minflt, 12=majflt) and assign to usage. -
.supported? ⇒ Boolean
Whether the memory usage can be captured on this system.
Class Method Details
.capture(pid, faults: true, **options) ⇒ Object
Capture memory usage from /proc/[pid]/smaps (and map count from VmFlags) and /proc/[pid]/maps. Optionally fill fault counters from /proc/[pid]/stat.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/process/metrics/memory/linux.rb', line 51 def self.capture(pid, faults: true, **) File.open("/proc/#{pid}/smaps_rollup") do |file| usage = Memory.zero file.each_line do |line| if /(?<name>.*?):\s+(?<value>\d+) kB/ =~ line if key = SMAP[name] # Convert from kilobytes to bytes: usage[key] += value.to_i * 1024 end end end usage.map_count += File.readlines("/proc/#{pid}/maps").size # Also capture fault counters if requested: if faults self.capture_faults(pid, usage) end return usage end rescue Errno::ENOENT, Errno::ESRCH, Errno::EACCES # Process doesn't exist or we can't access it. return nil end |
.capture_faults(pid, usage) ⇒ Object
Extract minor and major page fault counters from /proc/[pid]/stat (proc(5): fields 10=minflt, 12=majflt) and assign to usage.
14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/process/metrics/memory/linux.rb', line 14 def self.capture_faults(pid, usage) stat_content = File.read("/proc/#{pid}/stat") # The comm field can contain spaces and parentheses; find the closing ')': closing_paren_index = stat_content.rindex(")") return unless closing_paren_index fields = stat_content[(closing_paren_index + 2)..].split(/\s+/) # proc(5): field 10=minflt, 12=majflt; our fields array is 0-indexed from field 3. usage.minor_faults = fields[10-3].to_i usage.major_faults = fields[12-3].to_i rescue # Ignore. end |
.supported? ⇒ Boolean
Whether the memory usage can be captured on this system.
43 44 45 |
# File 'lib/process/metrics/memory/linux.rb', line 43 def self.supported? true end |