Alexander Dymo
2010-May-14 16:53 UTC
Strange situation: last 3 requests and responses are stored in memory!
Hey, We recently spotted strange behavior with Rails 2.3. For some reason last 3 requests/responses (and all connected objects - controller, views, controller''s instance variables, etc) are always present in memory in _production_ mode. This is how we see the problem. Create an empty Rails application with a simple controller like this: === app/controllers/default_controller.rb ==class A end class DefaultController < ApplicationController def index @a = A.new GC.start x = 0 ObjectSpace.each_object(A) do |o| x+=1 end puts x render :text => "Hello!" end end Now launch the application (in a production mode) and perform requests. You''ll see that: - after first request: there''s one object of class A in memory - after second request: there''re two objects of class A in memory!!! - after third request: there''re three objects of class A in memory!!! - after Nth request: there''re still three objects of class A in memory!!! The complete log output will look like this: =================================================> Booting WEBrick => Rails 2.3.5 application starting on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2010-05-14 16:25:18] INFO WEBrick 1.3.1 [2010-05-14 16:25:18] INFO ruby 1.8.7 (2010-01-10) [i486-linux] [2010-05-14 16:25:23] INFO WEBrick::HTTPServer#start: pid=22164 port=3000 1 Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 16:25:24) [GET] Completed in 29ms (View: 3 | 200 OK [http://localhost/default/index] 2 Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 16:25:28) [GET] Completed in 19ms (View: 0 | 200 OK [http://localhost/default/index] 3 Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 16:25:31) [GET] Completed in 20ms (View: 1 | 200 OK [http://localhost/default/index] 3 Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 16:25:34) [GET] Completed in 18ms (View: 1 | 200 OK [http://localhost/default/index] 3 ================================================ I''d expect to have only one object of class A in memory because after the request ends and the new one starts nothing should hold a reference to it. And we explicitly call GC.start before checking the objectspace. Also, if you replace ObjectSpace.each_object(A) do |o| with ObjectSpace.each_object(ActionController::Response) do |o| you''ll see the same result, you''ll get 3 responses in objectspace. So, the questions are: - who might hold 3 references to last 3 requests/responses? - how can I debug this? how can I find that reference? - can this be something related to rack? -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Aman Gupta
2010-May-25 23:44 UTC
Re: Strange situation: last 3 requests and responses are stored in memory!
On my system (ruby 1.8.7 (2010-01-10 patchlevel 249) [i686- darwin10.3.0]), your example maxes out at two copies of A, which is not _that_ strange. The previous requests'' objects could still be referenced on the stack somewhere or maybe somewhere in WEBrick''s internals. You can use memprof to figure out where the references are coming from, but I would consider 2-3 GC calls to get rid of references to old request objects to be normal. Aman On May 14, 12:53 pm, Alexander Dymo <alexander.d...@gmail.com> wrote:> Hey, > > We recently spotted strange behavior with Rails 2.3. For some reason last 3 > requests/responses (and all connected objects - controller, views, > controller''s instance variables, etc) are always present in memory in > _production_ mode. > > This is how we see the problem. Create an empty Rails application with a > simple controller like this: > > === app/controllers/default_controller.rb ==> class A > end > > class DefaultController < ApplicationController > > def index > @a = A.new > GC.start > x = 0 > ObjectSpace.each_object(A) do |o| > x+=1 > end > puts x > render :text => "Hello!" > end > > end > > Now launch the application (in a production mode) and perform requests. > You''ll see that: > - after first request: there''s one object of class A in memory > - after second request: there''re two objects of class A in memory!!! > - after third request: there''re three objects of class A in memory!!! > - after Nth request: there''re still three objects of class A in memory!!! > > The complete log output will look like this: > > ================================================> => Booting WEBrick > => Rails 2.3.5 application starting onhttp://0.0.0.0:3000 > => Call with -d to detach > => Ctrl-C to shutdown server > [2010-05-14 16:25:18] INFO WEBrick 1.3.1 > [2010-05-14 16:25:18] INFO ruby 1.8.7 (2010-01-10) [i486-linux] > [2010-05-14 16:25:23] INFO WEBrick::HTTPServer#start: pid=22164 port=3000 > 1 > > Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 > 16:25:24) [GET] > Completed in 29ms (View: 3 | 200 OK [http://localhost/default/index] > 2 > > Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 > 16:25:28) [GET] > Completed in 19ms (View: 0 | 200 OK [http://localhost/default/index] > 3 > > Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 > 16:25:31) [GET] > Completed in 20ms (View: 1 | 200 OK [http://localhost/default/index] > 3 > > Processing DefaultController#index (for 127.0.0.1 at 2010-05-14 > 16:25:34) [GET] > Completed in 18ms (View: 1 | 200 OK [http://localhost/default/index] > 3 > ================================================> > I''d expect to have only one object of class A in memory because after the > request ends and the new one starts nothing should hold a reference to it. And > we explicitly call GC.start before checking the objectspace. > > Also, if you replace > ObjectSpace.each_object(A) do |o| > with > ObjectSpace.each_object(ActionController::Response) do |o| > you''ll see the same result, you''ll get 3 responses in objectspace. > > So, the questions are: > - who might hold 3 references to last 3 requests/responses? > - how can I debug this? how can I find that reference? > - can this be something related to rack? > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group athttp://groups.google.com/group/rubyonrails-core?hl=en.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.