Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Major factors for memory leaks in Rails

I am tryin to resolve a memory leak problem with Rails. I can see through New Relic that the usage of memory is increasing without ever decreasing.

This is a spinoff question from a large thread ( Memory constantly increasing in Rails app ) where I am trouble shooting the problem. What I need to know now is just:

What are major reasons/factors when it comes to memory leaks in Rails?

As far as I understand:

  • Global variables (such as @@variable) - I have none of these

  • Symbols (I have not created any specifically)

  • Sessions - What should one avoid here? Let's say I have a session keeping track of the last query one particular user used when to text-search the site. How should I kill it off?

  • "Leaving references" - What does this really mean? Could you give an example?

  • Any other bad coding examples you can give that will typically create memory leaks?

I want to use this information to look through my code so please provide examples!

Lastly, would this be "memory leaking code"?

ProductController
...
@last_products << Product.order("ASC").limit(5)
end

will that make @last_products bloat?

like image 809
Christoffer Avatar asked Sep 30 '12 22:09

Christoffer


People also ask

What is the main cause of memory leaks?

A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.

Which action can cause memory leak?

Common causes for these memory leaks are: Excessive session objects. Insertion without deletion into Collection objects. Unbounded caches.


1 Answers

The following will destroy applications.

Foo.each do |bar|
  #Whatever
end

If you have a lot of Foos that will pull them all into memory. I have seen apps blow up because they have a bunch of "Foos" and they have a rake task that runs through all the foos, and this rake task takes forever, lets say Y seconds, but is run every X seconds, where X < Y. So what happens is they now have all Foos in memory, more than once because they just keep pulling stuff into memory, over and over again.

While this can't exactly happen inside an front facing web app in the same way it isn't exactly efficient or wanted.

Instead of the above do the following

Foo.find_each do |bar|
  #Whatever
end

Which retrieves things and batches and doesn't put a whole bunch of stuff into your memory all at once.

And right as I finished typing this I realized this question was asked in September of last year... oh boy...

like image 149
rovermicrover Avatar answered Oct 18 '22 21:10

rovermicrover