Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 285 lines (204 sloc) 6.879 kB
bf31fbc @tmm1 new markdown README with examples for all the different apis and midd…
tmm1 authored
1 # memprof
2 (c) Joe Damato
3 @joedamato
4 http://timetobleed.com
5
6 Memprof is a Ruby level memory profiler that can help you find reference
7 leaks in your application.
8
9 Memprof can also do very lightweight function call tracing to figure out
10 which system and library calls are happening in your code.
11
12 # Installation
13
14 gem install memprof
15
16 # API
17
18 ## Memprof.stats
19
20 Memprof.start
21 12.times{ "abc" }
22 Memprof.stats
23 Memprof.stop
24
25 Start tracking file/line information for objects created after calling
26 `Memprof.start`, and print out a summary of file:line/class pairs
27 created.
28
29 12 file.rb:2:String
30
31 *Note*: Call `Memprof.stats` again after `GC.start` to see which objects
32 are cleaned up by the garbage collector:
33
34 Memprof.start
35 10.times{ $last_str = "abc" }
36
37 puts '=== Before GC'
38 Memprof.stats
39
40 puts '=== After GC'
41 GC.start
42 Memprof.stats
43
44 Memprof.stop
45
46 After `GC.start`, only the very last instance of `"abc"` will still
47 exist:
48
49 === Before GC
50 10 file.rb:2:String
51 === After GC
52 1 file.rb:2:String
53
54 *Note*: Use `Memprof.stats("/path/to/file")` to write results to a file.
55
56 *Note*: Use `Memprof.stats!` to clear out tracking data after printing
57 out results.
58
59 ## Memprof.track
60
61 Simple wrapper for `Memprof.stats` that will start/stop memprof around a
62 given block of ruby code.
63
64 Memprof.track{
65 100.times{ "abc" }
66 100.times{ 1.23 + 1 }
67 100.times{ Module.new }
68 }
69
70 For the block of ruby code, print out file:line/class pairs for
71 ruby objects created.
72
73 100 file.rb:2:String
74 100 file.rb:3:Float
75 100 file.rb:4:Module
76
77 *Note*: You can call GC.start at the end of the block to print out only
78 objects that are 'leaking' (i.e. objects that still have inbound
79 references).
80
81 *Note*: Use `Memprof.track("/path/to/file")` to write the results to a
82 file instead of stdout.
83
84 ## Memprof.dump
85
86 Memprof.dump{
87 "hello" + "world"
88 }
89
90 Dump out all objects created in a given ruby block as detailed json
91 objects.
92
93 {
94 "_id": "0x15e5018",
95
96 "file": "file.rb",
97 "line": 2,
98
99 "type": "string",
100 "class_name": "String",
101
102 "length": 10,
103 "data": "helloworld"
104 }
105
106 *Note*: Use `Memprof.dump("/path/to/filename")` to write the json output
107 to a file, one per line.
108
109 ## Memprof.dump_all
110
111 Memprof.dump_all("myapp_heap.json")
112
113 Dump out all live objects inside the Ruby VM to `myapp_heap.json`, one
114 per line.
115
116 ### [memprof.com](http://memprof.com) heap visualizer
117
118 # load memprof before requiring rubygems, so objects created by
119 # rubygems itself are tracked by memprof too
120 require `gem which memprof/signal`.strip
121
122 require 'rubygems'
123 require 'myapp'
124
125 Installs a `URG` signal handler and starts tracking file/line
126 information for newly created ruby objects. When the process receives
127 `SIGURG`, it will fork and call `Memprof.dump_all` to write out the
128 entire heap to a json file.
129
130 Use the `memprof` command to send the signal and upload the heap to
131 [memprof.com](http://memprof.com):
132
133 memprof --pid <PID> --name my_leaky_app --key <API_KEY>
134
135 ## Memprof.trace
136
137 require 'open-uri'
138 require 'mysql'
139 require 'memcached'
140
141 Memprof.trace{
142 10.times{ Module.new }
143 10.times{ GC.start }
144 10.times{ open('http://google.com/') }
145 10.times{ Mysql.connect.query("select 1+2") }
146 10.times{ Memcached.new.get('memprof') }
147 }
148
149 For a given block of ruby code, count:
150
151 - number of objects created per type
152 - number of calls to and time spent in GC
153 - number of calls to and time spent in connect/read/write/select
154 - number of calls to and time spent in mysql queries
155 - number of calls to and responses to memcached commands
156 - number of calls to and bytes through malloc/realloc/free
157
158 The resulting json report looks like:
159
160 {
161 "objects": {
162 "created": 10,
163 "types": {
164 "module": 10, # Module.new
165 }
166 },
167
168 "gc": {
169 "calls": 10, # GC.start
170 "time": 0.17198
171 },
172
173 "fd": {
174 "connect": {
175 "calls": 10, # open('http://google.com')
176 "time": 0.0110
177 }
178 },
179
180 "mysql": {
181 "queries": 10, # Mysql.connect.query("select 1+2")
182 "time": 0.0006
183 },
184
185 "memcache": {
186 "get": {
187 "calls": 10, # Memcached.new.get('memprof')
188 "responses": {
189 "notfound": 10
190 }
191 }
192 }
193 }
194
195 *Note*: To write json to a file instead, set `Memprof.trace_filename =
196 "/path/to/file.json"`
197
198 ## Memprof.trace_request
199
200 Memprof.trace_request(env){ @app.call(env) }
201
202 Like `Memprof.trace`, but assume an incoming Rack request and include
203 information about the request itself.
204
205 {
206 "start" : 1272424769750716,
207 "tracers" : {
208 /* ... */
209 },
210 "rails" : {
211 "controller" : "home",
212 "action" : "index"
213 },
214 "request" : {
215 "REQUEST_URI" : "/home",
216 "REQUEST_METHOD" : "GET",
217 "REMOTE_ADDR" : "127.0.0.1",
218 "QUERY_STRING" : null
219 },
220 "time" : 1.3442
221 }
222
223 # Middlewares
224
225 ## Memprof::Middleware
226
227 require 'memprof/middleware'
228 config.middlewares.use(Memprof::Middleware)
229
230 Wrap each request in a `Memprof.track` to print out all object
231 location/type pairs created during that request.
232
233 *Note*: It is preferable to run this in staging or production mode with
234 Rails applications, since development mode creates a lot of unnecessary
235 objects during each request.
236
237 *Note*: To force a GC run before printing out a report, pass in
238 `:force_gc => true` to the middleware.
239
240 ## Memprof::Tracer
241
242 require 'memprof/tracer'
243 config.middleware.insert(0, Memprof::Tracer)
244
245 Wrap each request in a `Memprof.trace_request` and write results to
246 `/tmp/memprof_tracer-PID.json`
247
248 ## Memprof::Filter
249
250 Similar to `Memprof::Tracer`, but for legacy Rails 2.2 applications.
251
252 class ApplicationController < ActionController::Base
253 require 'memprof/tracer'
254 around_filter(Memprof::Filter)
255 end
256
257 # Compatibility
258
259 Memprof supports all 1.8.x (MRI and REE) VMs, as long as they are 64-bit
260 and contain debugging symbols. For best results, use RVM to compile ruby
261 and make sure you are on a 64-bit machine.
262
263 The following ruby builds are not supported:
264
265 - Ruby on small/medium EC2 instances (32-bit machines)
266 - OSX's default system ruby (no debugging symbols, fat 32/64-bit
267 binary)
268
269 *Note*: Many linux distributions do not package debugging symbols by
270 default. You can usually install these separately, for example using
271 `apt-get install libruby1.8-dbg`
272
273 ## Coming soon
274
275 - support for Ruby 1.9
276 - support for i386/i686 ruby builds
277
278 # Credits
279
280 - Jake Douglas for the Mach-O Snow Leopard support
281 - Aman Gupta for various bug fixes and other cleanup
282 - Rob Benson for initial 1.9 support and cleanup
283 - Paul Barry for force_gc support in `Memprof::Middleware`
284
Something went wrong with that request. Please try again.