Class: Knj::Memory_analyzer
Overview
This class contains methods to debug memory-leaks. It prints its collected information as HTML.
Examples
ma = Knj::Memory_analyzer.new ma.write
Defined Under Namespace
Classes: Object_size_counter
Instance Method Summary collapse
-
#arrays(to = $stdout) ⇒ Object
Collects and writes a lot of information about the spawned arrays as HTML to the given IO.
-
#constants(to = $stdout) ⇒ Object
Collects information about the spawned classes and writes it as HTML to the given IO.
-
#garbage_collector(to = $stdout) ⇒ Object
Writes information about the garbage-collector to the given IO as HTML.
-
#global_vars(to = $stdout) ⇒ Object
Collects a lot of information and writes a lot of info about the spawned global variables as HTML to the given IO.
-
#hashes(to = $stdout) ⇒ Object
Collects and writes out a lot of information about the spawned hashes as HTML to the given IO.
-
#initialize ⇒ Memory_analyzer
constructor
Initialized various objects.
-
#write(to = $stdout) ⇒ Object
Writes all available memory-analyzer-information to the given IO.
-
#write_constant(to, mod, submod) ⇒ Object
Writes information about the given mod and submod to the given IO as HTML.
Constructor Details
#initialize ⇒ Memory_analyzer
Initialized various objects.
7 8 9 |
# File 'lib/knj/memory_analyzer.rb', line 7 def initialize @printed = {} end |
Instance Method Details
#arrays(to = $stdout) ⇒ Object
Collects and writes a lot of information about the spawned arrays as HTML to the given IO.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/knj/memory_analyzer.rb', line 106 def arrays(to = $stdout) arrays = {} ObjectSpace.each_object(Array) do |arr| begin arr = arr.sort rescue ArgumentError #When unable to sort regexps... next end keys = [] arr.each do |key| keys << key.class.name.to_s end if keys.empty? keystr = :empty else keystr = keys.join(":") end if !arrays.key?(keystr) arrays[keystr] = 1 else arrays[keystr] += 1 end end arrays.delete_if do |key, val| val < 100 end arrays = Knj::ArrayExt.hash_sort(arrays) do |h1, h2| h2[1] <=> h1[1] end to.write "<h1>Arrays</h1>\n" to.write "<table class=\"arrays list\">\n" to.write "\t<thead>\n" to.write "\t\t<tr>\n" to.write "\t\t\t<th>Array classes</th>\n" to.write "\t\t\t<th>Instances</th>\n" to.write "\t\t</tr>\n" to.write "\t</thead>\n" to.write"\t<tbody>\n" arrays.each do |key, val| to.write "\t\t<tr>\n" to.write "\t\t\t<td>#{Knj::Web.html(key)}</td>\n" to.write "\t\t\t<td>#{Knj::Locales.number_out(val, 0)}</td>\n" to.write "\t\t</tr>\n" end to.write "\t</tbody>\n" to.write "</table>\n" end |
#constants(to = $stdout) ⇒ Object
Collects information about the spawned classes and writes it as HTML to the given IO.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/knj/memory_analyzer.rb', line 209 def constants(to = $stdout) to.print "<h1>Constants</h1>\n" to.print "<table class=\"memory_analyzer list\">\n" to.print "\t<thead>\n" to.print "\t\t<tr>\n" to.print "\t\t\t<th>Class</th>\n" to.print "\t\t\t<th style=\"text-align: right;\">Instances</th>\n" to.print "\t\t</tr>\n" to.print "\t</thead>\n" to.print "\t<tbody>\n" constants_m = Module.constants constants_o = Object.constants constants_k = Kernel.constants constants = constants_m + constants_o + constants_k constants.sort.each do |mod| self.write_constant(to, Kernel, mod) end to.print "\t</tbody>\n" to.print "</table>\n" end |
#garbage_collector(to = $stdout) ⇒ Object
Writes information about the garbage-collector to the given IO as HTML.
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/knj/memory_analyzer.rb', line 34 def garbage_collector(to = $stdout) to.print "<h1>Garbage collector</h1>\n" if GC.enable to.print "<div>Garbage collector was not enabled! But it is again now!</div>\n" else to.print "<div>Garbage collector was already enabled.</div>\n" end GC.start end |
#global_vars(to = $stdout) ⇒ Object
Collects a lot of information and writes a lot of info about the spawned global variables as HTML to the given IO.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/knj/memory_analyzer.rb', line 165 def global_vars(to = $stdout) to.print "<h1>Global variables</h1>\n" to.print "<table class=\"global_variables list\">\n" to.print "\t<thead>\n" to.print "\t\t<tr>\n" to.print "\t\t\t<th>Name</th>\n" to.print "\t\t</tr>\n" to.print "\t</thead>\n" to.print "\t<tbody>\n" count = 0 Kernel.global_variables.each do |name| count += 1 #begin # global_var_ref = eval(name.to_s) #rescue => e # to.print "\t\t<tr>\n" # to.print "\t\t\t<td>Error: #{Knj::Web.html(e.message)}</td>\n" # to.print "\t\t</tr>\n" # # next #end #size = 0 #size = Knj::Memory_analyzer::Object_size_counter.new(global_var_ref).calculate_size #size = size.to_f / 1024.0 to.print "\t\t<tr>\n" to.print "\t\t\t<td>#{Knj::Web.html(name)}</td>\n" to.print "\t\t</tr>\n" end if count <= 0 to.print "\t\t<tr>\n" to.print "\t\t\t<td colspan=\"2\" class=\"error\">No global variables has been defined.</td>\n" to.print "\t\t</tr>\n" end to.print "\t</tbody>\n" to.print "</table>\n" end |
#hashes(to = $stdout) ⇒ Object
Collects and writes out a lot of information about the spawned hashes as HTML to the given IO.
47 48 49 50 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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/knj/memory_analyzer.rb', line 47 def hashes(to = $stdout) hashes = {} ObjectSpace.each_object(Hash) do |hash| begin keys_orig = hash.keys.sort rescue ArgumentError #When unable to sort regexps... next end keys = [] keys_orig.each do |key| keys << key.to_s end if keys.empty? keystr = :empty else keystr = keys.join(":") end if !hashes.key?(keystr) hashes[keystr] = 1 else hashes[keystr] += 1 end end hashes.delete_if do |key, val| val < 100 end hashes = Knj::ArrayExt.hash_sort(hashes) do |h1, h2| h2[1] <=> h1[1] end to.print "<h1>Hashes</h1>\n" to.write "<table class=\"hashes list\">\n" to.write "\t<thead>\n" to.write "\t\t<tr>\n" to.write "\t\t\t<th>Hash keys</th>\n" to.write "\t\t\t<th>Instances</th>\n" to.write "\t\t</tr>\n" to.write "\t</thead>\n" to.write"\t<tbody>\n" hashes.each do |key, val| to.write "\t\t<tr>\n" to.write "\t\t\t<td>#{Knj::Web.html(key)}</td>\n" to.write "\t\t\t<td>#{Knj::Locales.number_out(val, 0)}</td>\n" to.write "\t\t</tr>\n" end to.write "\t</tbody>\n" to.write "</table>\n" end |
#write(to = $stdout) ⇒ Object
Writes all available memory-analyzer-information to the given IO.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/knj/memory_analyzer.rb', line 12 def write(to = $stdout) to.print "<div style=\"width: 600px;\">\n" self.garbage_collector(to) GC.start self.arrays(to) GC.start self.hashes(to) GC.start self.constants(to) GC.start self.global_vars(to) GC.start to.print "</div>\n" end |
#write_constant(to, mod, submod) ⇒ Object
Writes information about the given mod and submod to the given IO as HTML.
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/knj/memory_analyzer.rb', line 234 def write_constant(to, mod, submod) submod_s = submod.to_s #return false if mod.name.to_s == "Object" or mod.name.to_s == "Module" return false if @printed.key?(submod_s) return false if mod.autoload?(submod) return false if !mod.const_defined?(submod) @printed[submod_s] = true instances = 0 invalid_submod_size_names = ["BasicObject", "Kernel", "Object", "FALSE"] if invalid_submod_size_names.index(submod_s) != nil size = "-" calc_size = false else size = 0 calc_size = true end classobj = mod.const_get(submod) begin ObjectSpace.each_object(classobj) do |obj| instances += 1 end rescue => e emsg = e..to_s if emsg.index("no such file to load") != nil or emsg.index("class or module required") != nil or emsg.index("uninitialized constant") != nil #return false else raise e end end if mod.to_s == "Kernel" or mod.to_s == "Class" or mod.to_s == "Object" mod_title = submod_s else mod_title = "#{mod.to_s}::#{submod_s}" end if instances > 0 to.print "\t\t<tr>\n" to.print "\t\t\t<td>#{mod_title.html}</td>\n" to.print "\t\t\t<td style=\"text-align: right;\">#{Knj::Locales.number_out(instances, 0)}</td>\n" to.print "\t\t</tr>\n" GC.start end if classobj.respond_to?("constants") classobj.constants.sort.each do |subsubmod| self.write_constant(to, classobj, subsubmod) end end end |