We recently upgraded our JRuby version from 1.3.x to 1.7.12 and suddenly noticed a huge regression in performance. Our requests were starting to slow down by 500 ms and that was huge for our customers.
We investigate what could be the potential issue and we used some low level tools like jstack to really nail down where threads were spending most of the time. After investigating, we saw that in our call trace lot of Thread.getStackTrace() calls were made by the app. This is an expensive call in Java.
We looked closely of where the calls were coming from and found out that deprecated warnings in Rails methods were causing these calls. Our first thought was that we will just disable the deprecated warnings in Rails by using this flag:
But we still continue to see getStackTrace calls in our call traces. We further dig down in Rails code and found out that it was the Kernel ‘caller’ method which was the culprit.
Caller method in JRuby will call the getStackTrace method and this was used by ‘ActiveSupport::Deprecation.warn’ method to report the exact line of the offending method.
Since it was passed in as an argument to deprecated warnings method, logic for switching on/off deprecated warnings has no effect. So the ‘silenced’ flag didn’t help at all.
So our solution was to fix all the deprecated warnings and wherever we couldn’t fix the warnings, we had to monkey patch Rails and completely remove the deprecated method call from the method.
So please beware of Rails deprecated warnings in JRuby!