Skip to content

Instantly share code, notes, and snippets.

@alvinsj
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alvinsj/2b327c4fc3a69ebf0417 to your computer and use it in GitHub Desktop.
Save alvinsj/2b327c4fc3a69ebf0417 to your computer and use it in GitHub Desktop.
#!/bin/env ruby
# lazy hack from Robert Klemme
module Memory
# sizes are guessed, I was too lazy to look
# them up and then they are also platform
# dependent
REF_SIZE = 4 # ?
OBJ_OVERHEAD = 4 # ?
FIXNUM_SIZE = 4 # ?
# informational output from analysis
MemoryInfo = Struct.new :roots, :objects, :bytes, :loops
def self.analyze(*roots)
an = Analyzer.new
an.roots = roots
an.analyze
end
class Analyzer
attr_accessor :roots
attr_reader :result
def analyze
@result = MemoryInfo.new roots, 0, 0, 0
@objs = {}
queue = roots.dup
until queue.empty?
obj = queue.shift
case obj
# special treatment for some types
# some are certainly missing from this
when IO
visit(obj)
when String
visit(obj) { @result.bytes += obj.size }
when Fixnum
@result.bytes += FIXNUM_SIZE
when Array
visit(obj) do
@result.bytes += obj.size * REF_SIZE
queue.concat(obj)
end
when Hash
visit(obj) do
@result.bytes += obj.size * REF_SIZE * 2
obj.each {|k,v| queue.push(k).push(v)}
end
when Enumerable
visit(obj) do
obj.each do |o|
@result.bytes += REF_SIZE
queue.push(o)
end
end
else
visit(obj) do
obj.instance_variables.each do |var|
@result.bytes += REF_SIZE
queue.push(obj.instance_variable_get(var))
end
end
end
end
@result
end
private
def visit(obj)
id = obj.object_id
if @objs.has_key? id
@result.loops += 1
false
else
@objs[id] = true
@result.bytes += OBJ_OVERHEAD
@result.objects += 1
yield obj if block_given?
true
end
end
end
end
ObjectSpace.
each_object.
with_object(Hash.new(0)){| obj, h|
h[obj.class] = (obj.class.to_s =~ /NewRelic/ ? Memory.analyze(obj).bytes : nil) }.
select{|k,v| puts "#{k} => #{v}" if k.to_s =~ /NewRelic/}
NewRelic::Agent::Configuration::EnvironmentSource => 4
NewRelic::Agent::Configuration::Manager => 423929
NewRelic::Agent::Configuration::DefaultSource => 2588
NewRelic::Agent::TracedMethodStack => 12
NewRelic::Agent::TransactionState => 44
NewRelic::Railtie => 89
NewRelic::LocalEnvironment => 4
NewRelic::Agent::Configuration::ManualSource => 420143
NewRelic::Agent::StartupLogger => 12
NewRelic::Control::Frameworks::Rails3 => 420220
NewRelic::Agent::Configuration::YamlSource => 546
NewRelic::Agent::NullLogger => 4
NewRelic::Agent::AgentLogger => 50
NewRelic::Agent::Commands::XraySessionCollection => 116
NewRelic::Agent::Commands::ThreadProfilerSession => 100
NewRelic::Agent::WorkerLoop => 44
NewRelic::Agent::Threading::BacktraceService => 92
NewRelic::Agent::Commands::AgentCommandRouter => 243
NewRelic::Agent::SqlSampler => 20
NewRelic::Agent::Transaction::ForcePersistSampleBuffer => 12
NewRelic::Agent::Transaction::SlowestSampleBuffer => 12
NewRelic::Agent::Transaction::XraySampleBuffer => 28
NewRelic::Agent::Transaction::DeveloperModeSampleBuffer => 12
NewRelic::Agent::TransactionSampler => 108
NewRelic::Agent::RulesEngine => 4
NewRelic::Agent::StatsHash => 4
NewRelic::Agent::StatsEngine => 28
NewRelic::Agent::EventListener => 164
NewRelic::Agent::NewRelicService::JsonMarshaller => 4
NewRelic::Agent::AuditLogger => 20
NewRelic::Control::Server => 46
NewRelic::Agent::NewRelicService => 150
NewRelic::Agent::Agent => 425851
NewRelic::Agent::SampledBuffer => 44
NewRelic::Agent::RequestSampler => 92
NewRelic::Agent::ErrorCollector => 103
NewRelic::Agent::CrossAppMonitor => 4
NewRelic::Agent::ShimAgent => 424949
NewRelic::Agent::VM::MonotonicGCProfiler => 20
NewRelic::Agent::Harvester => 424949
NewRelic::Agent::JavascriptInstrumentor => 4
NewRelic::Agent::SamplerCollection => 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment