class Cache
Cache for storing and looking up allocation metadata. Caches gem names, file locations, class names, and string values to reduce memory overhead during profiling.
Definitions
def initialize
Initialize a new cache with empty lookup tables.
Implementation
def initialize
@gem_guess_cache = Hash.new
@location_cache = Hash.new{|h, k| h[k] = Hash.new.compare_by_identity}
@class_name_cache = Hash.new.compare_by_identity
@string_cache = Hash.new
end
def guess_gem(path)
Guess the gem or library name from a file path.
Signature
-
parameter
pathString The file path to analyze.
-
returns
String The guessed gem name, stdlib component, or "other".
Implementation
def guess_gem(path)
@gem_guess_cache[path] ||=
if /(\/gems\/.*)*\/gems\/(?<gemname>[^\/]+)/ =~ path
gemname
elsif /\/rubygems[\.\/]/ =~ path
"rubygems"
elsif /ruby\/2\.[^\/]+\/(?<stdlib>[^\/\.]+)/ =~ path
stdlib
elsif /(?<app>[^\/]+\/(bin|app|lib))/ =~ path
app
else
"other"
end
end
def lookup_location(file, line)
Look up and cache a file location string.
Signature
-
parameter
fileString The source file path.
-
parameter
lineInteger The line number.
-
returns
String The formatted location string "file:line".
Implementation
def lookup_location(file, line)
@location_cache[file][line] ||= "#{file}:#{line}"
end
def lookup_class_name(klass)
Look up and cache a class name.
Signature
-
parameter
klassClass The class object.
-
returns
String The class name or
unknownif unavailable.
Implementation
def lookup_class_name(klass)
@class_name_cache[klass] ||= ((klass.is_a?(Class) && klass.name) || "unknown").to_s
end
def lookup_string(obj)
Look up and cache a string value.
This maps the original string to a shortened representation.
Strings are truncated to 64 characters to reduce memory usage.
Signature
-
parameter
objString The string object to cache.
-
returns
String A cached copy of the string (truncated to 64 characters).
Implementation
def lookup_string(obj)
# This string is shortened to 64 characters which is what the string report shows. The string report (by value) can still list unique strings longer than 64 characters separately because the `object_id` of the shortened string will be different.
@string_cache[obj] ||= obj[0, 64]
rescue RuntimeError => error
# It is possible for the String to be temporarily locked from another Fiber which raises an error when we try to use it as a hash key. i.e: `Socket#read` locks a buffer string while reading data into it. In this case we `#dup`` the string to get an unlocked copy.
if error.message == "can't modify string; temporarily locked"
@string_cache[obj.dup] ||= obj[0, 64]
else
raise
end
end