Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!204.52.135.9.MISMATCH!newsfeed.hal-mli.net!feeder1.hal-mli.net!69.16.185.16.MISMATCH!npeer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail From: Lew Newsgroups: comp.lang.java.programmer Subject: Re: Closing/Despose of JFrame Date: Thu, 28 Jun 2012 09:47:55 -0700 (PDT) Organization: http://groups.google.com Lines: 112 Message-ID: References: <5752befc-aca1-46f9-81d9-f3992bf756e7@googlegroups.com> NNTP-Posting-Host: 69.28.149.29 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 X-Trace: posting.google.com 1340902076 32530 127.0.0.1 (28 Jun 2012 16:47:56 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 28 Jun 2012 16:47:56 +0000 (UTC) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=69.28.149.29; posting-account=CP-lKQoAAAAGtB5diOuGlDQk0jIwmH0T User-Agent: G2/1.0 X-Received-Bytes: 5265 Xref: csiph.com comp.lang.java.programmer:15725 markspace wrote: > Jesper Johnsen wrote: >> How do I remove an object lets say a JFrame from memory? >> I know that the garbage collector handles this - but this simple example does not release itself... >> java.exe uses 10mb in the first wait stage, this increases to 20mb when the JFrame is shown, but the memory usage never returns to the initial 10mb. > > So the garbage collector never removes the object from memory - why? > > > Why? Because the garbage collector never needs to remove the object. > You're using 20mb out of maybe 100mb to 1000mb or more? So the garbage > collector looks at that and says "plenty o' room left!" and doesn't run. > > It's weird if you're used to having explicit control over object > destruction, but it works. More importantly it's efficient. Waiting, > and then removing lots of objects at once, is actually best for > throughput in the long run. > > If you really need different behavior, check out Oracle's documentation > on tuning the garbage collector. You can choose what I believe is > called an incremental garbage collector which will work more like what > you are thinking. > > > > Found via Google with search terms "java garbage collection tuning". > Learn to STFW. Shut the front window? :-) Both oracle.com and https://www.ibm.com/developerworks/java/ have excellent articles and white papers on Java garbage collection, how it works and how you can fine tune it. Make sure you have a problem before you try to solve it, but it is always useful to gather knowhow. The default generational garbage collector works well, especially for idiomatic Java. As Brian Goetz points out in his Developerworks articles, the allocation cost in the heap is very tiny, on the order of a dozen or so machine instructions. Deallocation is likewise not very expensive for short-lived objects. Young objects live in the young generation heap, and dead ones are ignored during minor GCs. If most objects are short-lived, as should be true if one follows best practices for scoping variables, then most GC cycles will gather about 3% of live objects, ignoring the 97% of unreachable ones. This is a very fast copy and shouldn't burden your throughput very much. When objects survive enough minor GC cycles, they move to the tenured generation, a different area of heap. These are only collected during major GC cycles, which use different and somewhat slower algorithms under default setup. The major cycles are the ones we tend to notice. So if an object is going to survive to tenure, aim to have it survive for a very long time thereafter. Otherwise use idioms that help objects die young. For example, dying young: public class Example { Collection foos = getSomeFoos(); public void run() { for (Foo foo : foos) { Bar bar = foo.obtainBar(); // do whatever with 'bar' // 'bar' falls out of scope // if nothing else points to the same object // it is gone in the next minor GC } } } Dying old: public class Example { Collection foos = getSomeFoos(); Bar bar; // the elephant in the room public void run() { for (Foo foo : foos) { bar = foo.obtainBar(); // do whatever with 'bar' // 'bar' does not fall out of scope // The last reference from the loop lasts as // long as this instance does, and could // tenure the 'Bar' it points to } } } So coding things the first way, which chance are is more correct logically, tends to reduce the impact of GC on performance. It tilts the GC towards very rapid, almost negligible young-generation collections and less toward the slower, more intrusive tenured-generation collections. Read widely and carefully. There are some notable urban legends out there, such as the advice to set all references to 'null' when finished with them. There are specific times to do so, such as when a collection such as a 'Stack' is holding hidden references ("packratting", or the Java version of a memory leak). Otherwise it's just superstition. -- Lew