Memory grows indefinitely in an empty Rails app
Asked Answered
A

2

20

I can't figure out why my Rails app (hosted on Heroku (cedar)) keeps allocating more and more memory. If I didn't know any better I'd say that this a memory leak in Ruby/Rails, but since I'm completely new to Ruby/Rails, I feel like I'm missing something completely obvious.

I'm using Rails defaults generated by rails new, and completely up-to-date gems:

source 'https://rubygems.org'

gem 'rails', '3.2.8'

group :development do
  gem 'sqlite3'
end

group :assets do
  gem "sass-rails", "~> 3.2.5"
  gem "coffee-rails", "~> 3.2.2"
  gem "uglifier", "~> 1.3.0"
end

gem "jquery-rails", "~> 2.1.2"

group :production do
  gem 'newrelic_rpm'
  gem "pg", "~> 0.14.1"
end

I'm using the default newrelic config. I have zero models and one controller, nothing_controller.rb, which was generated using rails generate controller nothing:

class NothingController < ApplicationController
  def index
  end
end

I deleted public/index.html and added an empty views/nothing/index.html.erb. The only other thing I did to the generated app was add a route to routes.rb:

Nothing::Application.routes.draw do
  root :to => "nothing#index"
end

I committed, pushed it to Heroku, then wrote a quick script that would load my Heroku page every 10 seconds. This is what my New Relic reports:

https://static.mcmap.net/file/mcmap/ZG-AbGLDKwfpKnMxcF_AZVLQamyA/cbm4k.png

That's all there is to it. Memory just keeps increasing like that until it passes Heroku's limit of 512MB. The code in this app is pretty much the same as the code I've seen in the tutorial I followed. I don't understand what I'm doing wrong.

Any guidance would be greatly appreciated.

EDIT (9/12): In case it's relevant, I'm using ruby 1.9.

Code I'm using to hit the server (C#):

using (var wc = new WebClient())
  for (;; Thread.Sleep(10000))
    wc.DownloadString("http://vast-earth-9859.herokuapp.com/");

EDIT (9/13): Going to try disabling New Relic and seeing if it still R14s.

Antalkali answered 12/9, 2012 at 22:57 Comment(9)
Seeing the code that hits your server every 10s would be nice.Granddaddy
Sure. Added. As a side note, the reason I decided to do this was because a fairly basic app I wrote had the some problem and would run out of memory after ~400 page views.Antalkali
Try adding Oink to monitor what's getting instantiated. RubyProf may take some finagling, but if you can get it to work, that would provide more insight. Generally, memory is supposed to increase -- this is good. Additionally, it's supposed to be garbage collected when it is not used as often.Symonds
I can run Oink fine locally (each request says Instantiation Breakdown: Total: 0, as expected) but I can't figure out how to use it on Heroku. Logs aren't stored in logs/* and a cursory Google search did not tell me much. I don't get it though...is something wrong with my Rails or something? I feel like I'm the only one with this problem. How does everyone else's heroku+rails apps not run out of memory?Antalkali
You definitely seem to have a weird problem. Forward this to heroku support.Symonds
And post the solution here when you find out!Symonds
On it. First going to let this empty app R14.Antalkali
What version of newrelic gem is in your Gemfile.lock? THere were some memory issues a while back, which may be resolved by running bundle update newrelic or manually specifying the latest version of the gem.Venenose
Sorry for the late response. Have had nearly no free time lately. jakeonrails was correct. After updating newrelic with bundle update my rails apps no longer run out of memory. They still go up to ~300MB, at which point they drop back down.Antalkali
P
5

Trying removing newrelic gem. I had have same issue on heroku and culprit was newrelic gem. You can check your current object that is memory. Below code show you the object count.

ObjectSpace.each_object.with_object(Hash.new(0)){|obj, h| h[obj.class] +=1 }.select{|k,v| puts "#{k} => #{v}" if k == String || k == Array || k == Hash}
Penang answered 22/10, 2013 at 12:14 Comment(1)
ObjectSpace.count_objects will produce a similar output.Maharajah
O
2

Once the memory exceeds(512 MB) the limit on heroku, it won't get the memory down immediately by restarting the app or by changing code. It will keep on growing and slows it further, heroku itself kills the process when it hits heroku's memory threshold (not sure how much it is).

There are various things might have caused the memory leaks, following are the few 1. Continuous exceptions thrown 2. Getting lot of data in a single request.

Testing it on local machine won't help since you won't have any memory restriction on your machine.

Do the following to see the heroku log and figure what are the latest errors what are items take time.

heroku logs -a <application name> -n<number of lines>

Stop the application for day or so then you can the change code and start the application.

Okun answered 3/10, 2012 at 11:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.