4 Replies Latest reply on Feb 27, 2011 6:49 PM by kragoth

    Conversation, arrays inside arrays, memory issue?

    jfaath

      I have a conversation scoped action class that contains a list of objects that themselves may have a list of children...like an n-ary tree.  I use this list to build a UI where each item is a link.  Clicking on a link performs an ajax request where some other stuff is done on the page, but more importantly, this list needs to be recreated from scratch.


      So, I thought it would be wise to wipe out all the items in the list as well as all the child items, etc. before I rebuild it.  Unfortunately, that leads to a concurrent modification exception (why is that, I wonder?).  So what I ended up doing is just creating a new list and pointing the variable to this new list, thereby de-referencing the old list.


      My concern is that this may lead to a memory leak?  As the user is clicking through these links, more and more of these tree lists will be de-referenced as brand new ones are built.  I guess I'm looking for advice as to whether this is a bad idea or if I'm just being paranoid.  Any insight would be appreciated!


      Regards,


      -JF

        • 1. Re: Conversation, arrays inside arrays, memory issue?
          kragoth

          De-referencing an object means that java's garbage collection will come along and get rid of it for you. If this did not happen every java app in the world would only live for mere minutes before there was no memory left. Hibernate/Spring/Seam they all create many many many references to objects and rely very heavily on the fact that once they are done with them java's garbage collection will take care of freeing up the memory they had used.


          It probably wouldn't hurt to go read about java's garbage collection for your own peace of mind though.


          List<String> myList = new ArrayList<String>();
          
          function test() {
          
              for(int i = 0; i < 10; i++) {
                  myList.add("NUMBER:"+i);
              }
          
              System.out.println("At this point in time we have a list containing " + myList.size() + " elements");
          
              myList = new ArrayList<String>();
          
              System.out.println("The 10 strings that were in the list are now able to be garbage collected. Java will pick them up when it next runs the GC process");
              System.out.println("At this point in time we have a list containing " + myList.size() + " elements");
          
          }
          

          • 2. Re: Conversation, arrays inside arrays, memory issue?
            monkeyden

            Hey Jeff,


            Good to see you.  I hope you're well.  Tim is correct and, to take it a step further, the multi-threaded generational garbage collection facility in Java is remarkably efficient for most applications.  Depending on the characteristics of the application (of course), the vast majority of objects don't outlive the young generation.  By default, the garbage collector takes advantage of this by doing minor collections (a collection of already dereferenced/dead objects) in the young generation, saving major collections (often containing many more live objects) for the tenured generation.  Nearly everything about the collector, from the size of each generation to collection frequency, can be tailored to the application.  However, I've found that, apart from heap size adjustments, most apps (web apps, at least) will benefit from the default settings and behavior.


            K

            • 3. Re: Conversation, arrays inside arrays, memory issue?
              jfaath

              Yes, I know about the java garbage collector and I've done my fair share of profiling applications. The patronizing response on brushing up on the garbage collector was unnecessary.


              This particular instance gave me pause because Seam has a lot of stuff going on behind the scenes.  I couldn't manually clear the array myself (as I stated, concurrent mod exception) which tells me that something has a hold of the object.  I'm in conversation scope so I have no idea if this something is still going to hold on to the object when I release my reference to it.  The calls were all ajax-based and I am not that familiar with how the whole faces component tree is handling things.  And frankly, I have an unnatural fear of arrays inside arrays inside arrays probably from my old C/C plus plus days.  Anyway, the whole point is moot as I've gone in a different direction.


              And there are plenty of things to watch out for in a framework as complicated as Seam.  Maybe you should read up on them.  This will get you started:
              http://seamframework.org/Community/15GotchasInSeam

              http://seamframework.org/search_d.seam?query=leak

              http://seamframework.org/search_d.seam?query=memory

              • 4. Re: Conversation, arrays inside arrays, memory issue?
                kragoth

                Jeff Faath wrote on Feb 25, 2011 13:06:


                Yes, I know about the java garbage collector and I've done my fair share of profiling applications. The patronizing response on brushing up on the garbage collector was unnecessary.

                This particular instance gave me pause because Seam has a lot of stuff going on behind the scenes.  I couldn't manually clear the array myself (as I stated, concurrent mod exception) which tells me that something has a hold of the object.  I'm in conversation scope so I have no idea if this something is still going to hold on to the object when I release my reference to it.  The calls were all ajax-based and I am not that familiar with how the whole faces component tree is handling things.  And frankly, I have an unnatural fear of arrays inside arrays inside arrays probably from my old C/C plus plus days.  Anyway, the whole point is moot as I've gone in a different direction.

                And there are plenty of things to watch out for in a framework as complicated as Seam.  Maybe you should read up on them.  This will get you started:
                http://seamframework.org/Community/15GotchasInSeam

                http://seamframework.org/search_d.seam?query=leak

                http://seamframework.org/search_d.seam?query=memory



                I'm guessing your concurrent modification is because you are trying to change a collection inside an AJAX request while the component tree is also trying to use that collection in one of it's phases. Or maybe there were multiple AJAX requests firing and you just needed to put an a4j:queue  on the page. But, you've got another solution now anyway right?


                By the way, it wasn't patronizing. You asked a question about causing a memory leak because you were dereferencing old values and replacing them with new. Without knowing your previous experience with programming one must start with the simple stuff first. If I started with soft references and how that effects GC and you were relatively new to Java I'd be wasting my time and yours. So, if you understand it then maybe you should have changed your question. Maybe what you are really asking is, Does Seam maintain references to old values in such a way that replacing a value in a Seam bean will cause an 'effectual' memory leak. Even then, the only time Seam is going to reference a value directly is in the instance of @Out (or variations of this) and possibly params (but not necessarily Seam in this respect). This in itself was not part of your question so, I was left very little to work on and thus simple object references were the topic.


                As no code was shown here it is a little difficult to check exactly what is going on but I'm sure you understand the component tree and how it will hold a reference to it's value in it's saved variables (assuming server side state saving and all that) and that maybe this is where other reference was being held. If this is the case it still wont cause a memory leak because the next time that the component evaluates the value expression and calls save variables it will overwrite the old value and then all references to the original value should be cleared.


                With regards to your links....how is that not patronizing? Besides the fact that running a search has no relevance to the issue at hand. Not to mention the fact that the vast majority of topics you will turn up with that query have nothing to do with Seam in the first place but, rather another library people are using with Seam. Secondly, the vast majority of real memory leaks that have been found in Seam have been fixed. I'm not saying none exist but, under general usage patterns Seam is not a flimsy framework that's gona chew up all your memory in a big day's load.


                But, getting back to the original topic. If your worried about memory leaks why not just run a profiler on your app and watch? You say you've done profiling before so....fire one up and take a look. Java Profilers are so easy and good these days.


                And with regards to finding out what held the lock on your array. Put a breakpoint on the ConcurrentModException and then check your stack. I'm pretty sure you'll find it in there.