I've got an app which creates a bunch (hundreds) of URL connections and reads in the data from them using a BufferedReader for each one. It's no surprise that my app takes a ton of memory, but I wonder if the Readers are not getting garbage collected and in fact staying in memory long after I am finished with them. I create them locally inside a method and do not retain any refernce to them. Also, when I am finished reading from them I close them up. Is there anything else I should do to make sure they are flushed from the system? Do I have to do anything to the URLConnections to make sure they are not taking up too much memory? *Sigh* memory management, it sux Micah
Notice that the JVM may decide to not call the gc as long as there is enough free memory left. Do you get any memory problems? [This message has been edited by Ilja Preuss (edited December 10, 2001).]
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Joined: Jun 11, 2001
Yes, I eventually get a java.lang.OutOfMemoryError. Would it possibly be helpful to call the GC explicitly?
Joined: Jul 11, 2001
You shouldn't need to call the gc explicitely. Could you please post some code? Preferably a complete short program exhibiting the problem. What JRE are you using (use "java -version" to find out...)?
I often find it useful to run java using the -verbose:gc option while debugging. Every time GC runs you get a nice printout or what the meory usage was before and after GC ran. So you end up with a running log of memory usage. You can combine this with additional diagnostic print statements to get a good overall picture of what's going on in your machine. Try explicity calling System.gc() before and after creating each Reader, and before and after closing the Reader and setting the variable to null. In general you don't need to call gc(), but for diagnostic purposes it's nice to be sure when it has occurred, and with the verbose option you get added memory reportage. (And I know you said the Reader is in a local variable, so you don't need to set it to null - except that if you want to call System.gc() and see the Reader collected, it's a little clearer if you do it in the same method that the Reader was defined in. Which means the local var is still in scope. What about the URLConnections? Is there a finite set of them that you keep for the life of the program, or do those get gc'ed too? You may want to look at memory usage before and after these are created / dropped. Even if you don't want or plan to ever let these out of memory, it may be useful to intentionally set these to null after you've used them a while, just to see how much GC can reclaim from them. Note that the output of -verbose:gc isn't guaranteed to be exact (neither is the output from Runtime's freeMemeory() and totalMemry()) - but it's generally close enough to give you a pretty good idea what's going on. For test purposes it may also be useful to exaggerate effects by creating many more Readers or URLConnections than you actually need - so that when you see usage go up or down, it's more obvious what the cause is. Good luck...