I have a servlet which creates a new Action class for each request. Each action class defines a Logger for logging as a static variable: private static Logger logger = Logger.getLogger(className); Once the action class completes, will this never be garbage collected because of the static logger that I created? Another solution is to do something like Struts, where there is only one instance of each Action class that is shared for the application. Is this a better design? Thanks Brian
Right, the logger you get here will remain in memory forever. The good news is getLogger() is called once, a single instance of Logger is created, and this is probably exactly what you need. (There might be more instances of Logger if Logger.getLogger() hands out new instances every time or some times based on the class argument.) There have been some neat threads on the performance benefits of pooled objects or singleton objects shared between many threads. Turns out the headaches of managing concurrency may not be worth while and just a few "synchronized" methods can outweigh the cost of creating and GC-ing objects. Bottom line: it depends. Do what feels right, use profiling to prove it's good or bad.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: Nov 02, 2000
The action classes will get garbage collected, right? even though they contain a reference to the static Logger? Thanks Brian
The rule is that any unreachable class gets garbage collected. That is, if there is no valid reference to an object on the heap anymore, then it's unreachable and the GC reclaims the space. Doesn't matter what that object refers to--it's getting reclaimed. (Well, it matters only in the sense that once the GC collects an object, all the references it held to other objects are now no longer--if those were the last references in the system to those other objects, then they are now unreachable and eligible for garbage collection.) Incidentally, I think you may be confusing two orthogonal concepts here. Unreachability is the issue with the GC, and it doesn't care whether references are static or not. In fact, an object itself cannot be "static"...only a reference can be static. A single object on the heap may have any number of references to it, static or not, at the same time. Once those references no longer reference it, it's eligible for collection. So, simply by setting a static reference to null, if that was the only reference to an object, that object is now going into the maw of the GC. The real issue here is one of scoping--static references never go out of scope--once a class is loaded, all its static references get loaded and once they're intialized that's it, they're there until you set 'em to null. This is the source of many a memory leak in Java. I've seen some approaches that attempt to remedy this. I'd say the best is simply managing those references and freeing them when it makes sense to do so. The next best approach I saw was less efficient but worth mentioning. First, no object in the entire system could have a static variable--all static data in the system was stored by a Singleton. Access to these variables was controlled by getters on the Singleton that would check to see if the reference was null, if so, populate it before handing back. This Singleton kicked off a thread that would periodically free all of the references. This was useful because for this application the amount of static data was huge, but the system only needed a small subset of this static data for any length of time. So, by using this system, only 1% or so of the total data was ever memory resident at one time, if the same bit of static data was accessed repeatedly over a relatively short time it was immediately available (except for the first access), and it worked out ok. Nowadays, though, I'd probably look into the same sort of approach except use the java.lang.ref package to do the same thing. I could probably figure out a way of doing this that would relax the "no static data" rule. sev