-
-
Notifications
You must be signed in to change notification settings - Fork 925
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
Memory leaks due to overwritten local variables being wrongly kept alive on the stack #4439
Comments
Thank you for the report! Indeed, you're seeing a side effect of the way our compiler manages temporary variables. In this case, the first Dummy instance gets stored in one of these temp vars before being assigned to the We're discussing ways to fix this. |
@subbuss and I realized that most of these trapped values in temp vars occurs as a result of a call. Since local variable assignments are handled as an operand we can add a little bit more smarts into our build and use the local variable as the result variable and get rid of this class of pinning an unwanted value. With patch now in IR (before):
Now is (after):
Also of note this eliminated 3 instrs in the test case. This could translate into some small improvement in interpreter performance because it will reduce number of temp vars and number of instructions. It should not affect JIT performance at all because the JVM is good like that (except it MIGHT help bytecode sizes and thus make the JVM make new choices -- unlikely though). My fix only changed some of builder to allow the lvar to be the rhs. I will break up some of the commits so I do not make some epic commit. This first commit fixes all calls and a few other instr which is a lion share of the cases. |
Awesomely speedy fix, thanks! 👍 |
Sorry for using this issue for solving my questions, but I see class names in visualvm and they are not what I get using that program for searching memory leaks in my applications. How can I see JRuby classes names in that form (rubyobj.Dummy)? Thank you very much. |
@brometeo you need to start JRuby with Also you may hit #4643, see the ticket for a workaround. |
Thank you very much. |
Environment
Running
jruby 9.1.7.0 (2.3.1) 2017-01-11 68056ae Java HotSpot(TM) 64-Bit Server VM 25.111-b14 on 1.8.0_111-b14 +jit [linux-x86_64]
onLinux maruchan 4.9.0-11-generic #12-Ubuntu SMP Mon Dec 12 16:18:23 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
.Expected Behavior
Example code:
On MRI this code seems to behave correctly (e.g. it does not leak memory) and I can get up to hundreds of thousands of iterations with < 16MB memory being used.
Actual Behavior
Running with jruby:
By pausing after a few iterations and looking at a memory dump (with
PAUSE_AFTER_ITERATIONS=1 jruby -J-Xmx200m leak_testcase.rb
), we can see the following:E.g. all instances of
Dummy
are still alive, whereas looking at the code we are creating a linked list but we never keep references to previous nodes so we should only have a single instance visible in memory.Looking at one of the instances, we see that they are being kept alive due to a reference stored on the stack:
and by asking for a list of stack references we see that there are two
Dummy
instances being referred to from the stack, not one as expected.It seems like the code generating is leaving the first dummy instance referenced on the stack and thus causing the memory leak as the whole list will be kept in memory, rather than just the last element.
We (@Talkdesk) hit this in production as we were iterating a large collection using
hyperclient
and thus were hitting memory limits even though we were doing it a slice at a time.The text was updated successfully, but these errors were encountered: