Hi Jan, Nice job trimming down the list of potential suspects!
I think that focusing on locals is a red herring. Locals do get collected and I can't imagine a JVM bug in that area, regardless of the OS, but I have a suspicion your loop is doing some side effects which are causing some other bigger objects to be retained. Sadly, this hypothesis seems to be invalidated by the fact that your code works properly on non-Windows JVM's, but it's not a 100% certainty yet. What are you doing in this loop? Can you post the code? Can you comment out some of what it does, leave the rest in and measure again? -- Cédric On Tue, May 3, 2011 at 9:01 AM, Jan Goyvaerts <[email protected]>wrote: > Hello Good Java People, > > I have a question about the way a JVM is supposed to collect local > variables. I'm a bit embarrassed as it looks to me it's a newbie question, > but I'm puzzled by what's on my screen. :-) > > I'm currently investigating a memory leak in a typical > (MySQL/Tomcat/Hibernate/Spring) server application. VisualVM indicates an > increasing number of instances of let's say @Entity class Foo. While the > batch process is supposed to process Foo one instance at a time. > > The process is a look in which a local variable of Foo is created, > processed and then evicted from the Hibernate session for good measure. > VisualVM indicates all the instances of Foo being held in memory by a GC > Root called "JNI Global". (Except one: the one currently being processed.) > Which usually indicates native code hasn't released yet the object. I have > no native code in this application. I've tried all sorts of strategies and > version of the JVM, but I'm still seeing the same behavior. Each new cycle > of the loop creates a new instance of Foo without releasing the previous > one. > > I was under the impression that local variables created during a cycle of a > loop are eligible for collection once the cycle is finished. I don't know > whether the JVM specification has to say about this. > > Betting on the fact local variables are created on the stack, I moved the > code inside the loop into a separate method - to have the stack explicitly > popped. Each cycle of the loop calls this method. The method creates the > instance of Foo, processes it, evicts it from the Hibernate session and > exists. And behold: No more Foo's ! > > But where it gets weird is that this is only happening on windows. Running > the very same code, with the same JVM release, on a 64bit Linux leaks Foo's. > Just as it was before. Both are Sun/Oracle JVM's btw. And I probably need to > add that the Linux JVM is running inside a VMWare VM. The windows JVM is > regularly purging its old generation while the Linux JVM isn't. > > So... if somebody can enlighten me about what's SUPPOSED to happen ? :-) > > (1) Are objects, referenced by local variables created inside a loop, > eligible for collection once the loop cycle ends ? I have always assumed > this was the case. > (2) Is there a rational explanation why the leak stops when the code is > moved into a sub-method ? > (3) Is there a difference between platforms concerning garbage collection ? > > Every clue as to what's possibly happing is welcome ! :-) > > Jan > > > > > > > > > > -- > You received this message because you are subscribed to the Google Groups > "The Java Posse" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/javaposse?hl=en. > -- You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
