krasicki said:
I want to explore that subject. Take all my arguments as good natured
curiosity.
take mine with the same good natured, willing advice.
Hopefully by now, all of the other replies within this thread has shown
you that the GC works to its own rules. If we haven't then thats our
fault - we need to find a way to describe it to you.
I disagree. When a Java programmer invokes a System.gc() call it frees
memory to the JVM at the earliest algorithmically determined time.
This is what I was talking about - at the 'earliest'. However, you need
to remember that 'earliest' might be only be at application shutdown time.
In
fact, I read an IBM or BEA article recently that advised programmers
not to use it because the application server's own garbage collection
management would get screwed up and you would likely hurt more than
help performance.
But let's get even more subtle.
Is that wise ;-)
Hagar, Bulka, and other java stylists
recommend explicit cleanup in deeply nested objects. In other words,
deeply nested cleanup routines that return exhausted object instances
back to a state of null. This, we are told, hints to the GC that it's
okay to free the associated memory.
What they mean by this, is that its easy in Java (and any other auto
memory manged language) to hold onto memory for unnecessarily long
times. This really is the only practical reason for nulling a reference
consider (very simple example)....
public void someMethodThatRunsForaLongTime() {
List aList = new ArrayList();
for (int i=0; i!= 100000;i++) {
aList.add("string = " + i);
}
// so now we have a huge arrayList with 100,000 string objects
// referenced by it - so thats 100,001 objects we have created
int listSize = aList.size();
for (int i=0;i!= 100000;i++) {
System.out.println(i);
}
} // only here at the end of the method, will the local reference
'aList' go out of scope and therefore the object that it points to, is
no 'orphaned' - which means the next time the GC runs, its can release
the memory of the arrayList and its contents.
However, if we put the line
aList = null;
just after we save the size of the aList in the 'listSize' int, then we
have made the object that the 'aList' reference points to, orphaned much
early that having to wait for the method to finish.
This is a very contrived example to show the concept of holding onto
objects for longer than is actually needed, but hopefully it serves its
purpose.
My question really comes back to a nagging doubt. Can an object
created by a factory class from a static method ever be clean enough to
free up? In other words, does the fact that it has referential roots
from a static method make the byproducts of that method all look
statically active (or immutable) to the GC?
At best as a developer we can System.gc, but the GC does not guarantee
to do anything right then as a result of the call.
In general sun's JVMs GC does most of the time, tend to run when
System.gc is called, but as developers we can't rely upon it happening
or continuing to work that way with either different runs of the
application or indeed with future JVM releases.
Therefore, we should not design our java apps with System.gc calls to
release memory, as they will not behavior the same from one run to another.
Rod Johnson, in J2EE Development without EJB, talks about generational
garbage collection techniques. Can anyone put static factory methods
into context considering these techniques?
Again, static methods make no difference to the life times of objects.
-snip-
Don't you really mean appropriately.
Actually I mean both of those.
Will using them a lot be worse or
better than using them a little. What does their proliferation have to
do with it?
The main problem with lots of static methods (although I'd call them
'functions'), is that they make the implementation of your application,
procedural rather than OO.
By this I meam, we lose all of the benefits of objects, as these
functions do not live on an object instance - they live on the class.
They can be useful for utility functions like 'System.out.println("..");
'. and are very useful for factory methods like yours or on a Singleton.
Other than that, try to prefer an instance method of an object.