-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ActionView's memory leak #22580
Comments
Are you dependent on ruby 2.1? If not I'd suggest you update to ruby 2.2. Rails 5 is pulling the trigger on all but ruby 2.2, so even we could ensure the method symbol is deleted from the symbol storage now, that would simply mean we are replicating (and perhaps breaking) functionality that Ruby 2.2 already fixed. |
Yeah, if this is fixed by upgrading to ruby 2.2, I don't think there's much we can do about it now... any change on our side seems too invasive to justify backporting to 4.2. 😕 |
@matthewd This issue affects many Rails applications all over the world. Upgrading to Ruby 2.2 (or to Rails 5) will be a big problem for tons of projects (especially for long term ones). For instance Debian will have Ruby 2.2 and higher in it's stable repositories in 1.5 years. |
Maybe I'm not understanding, but wouldn't this only be an issue in development environments, or if you're doing something weird in production, such as uncaching the templates. Say you have 100 template files, and 2 unicorn workers, you have a maximum of 200 of these methods, so 200 symbols created. |
The problem
I noticed that Rails (4.2.3) running on Ruby 2.1.5 has leak in the ActionView::Template class. My Rails applications are eating RAM slowly (it tooks weeks and even months) bite to bite. The reserved memory amount could grow from 130MB to 1.2GB with time (actually i didn't tested if the app could eat more).
Possible Cause
I believe that problem is somehow related to #14301.
This happens when calling ActionView::Template#compile. It evaluates the passed module and defines new method which is responsible for rendering of respective view (see this line). That method's name is in the following format:
_app_views_tv_channels__index_json_jbuilder___2694669448214811169_110696640
.Next #compile defines finalizer for the method. The finalizer does the following: it calls #undef_method on the module. Obviously that behavior removes the defined method, but the method's name is still in the symbols storage!
Experiment
Ruby implements method definition along with adding the method name symbol to the symbols storage:
Following snippet will undefine test_method. But Ruby 2.1.5 won't clear the method name from the symbols storage:
Ruby can garbage-collect the unused symbols only from the version 2.2.
Real-life experiment
I added this code to the ApplicationController:
And started watching the logs:
tail -f symbols.log
Per-process filtering:
tail -f symbols.log | grep 61247
I had symbols count growing more an more. Next i logged last symbols and got these ones:
Basing on this i calculated: each 100 processed requests were increasing RAM usage by at least 6-9KB.
The text was updated successfully, but these errors were encountered: