Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / May 2005

Tip: Looking for answers? Try searching our database.

A Java Brainteaser - a Static Factory method Narrative

Thread view: 
krasicki - 13 May 2005 02:28 GMT
I had never run into this before but have recently encountered code
that is something like:

// This code runs - I'm generalizing so forgive unintentional
oversights

// from a servlet
 MyWidget mw = FactoryClass.staticMethod();
 :

and in FactoryClass we find:

public static MyWidget staticMethod()  {
// yada yada
return new MyWidgetObject();
}

My questions are many but first and foremost is, *how is the memory
managed?*  Is each new object a new static object with immutable memory
assigned it or is the static memory recycled with each assignment to
mw?

Disclaimer:  YES,YES,YES - I know, I know... but take it for what it's
worth.
Wibble - 13 May 2005 02:44 GMT
The method to create a widget is static.  Not the widget allocated.
Its a plain old java object.

> I had never run into this before but have recently encountered code
> that is something like:
[quoted text clipped - 20 lines]
> Disclaimer:  YES,YES,YES - I know, I know... but take it for what it's
> worth.
krasicki - 13 May 2005 03:11 GMT
Are there garbage collection issues with these objects?
Wibble - 13 May 2005 04:17 GMT
> Are there garbage collection issues with these objects?

No, its irrelevant that they're allocated from a static
method.  It just allows the Factory class a little more
control of object creation than the 'new' method by itself.

In your example, the static just calls new.  Its a POJO.
krasicki - 13 May 2005 05:08 GMT
Alright, I'll buy that.  Let me reiterate what you're saying, just to
be clear.

If my example was (instead of a servlet lifecycle);

// from a short term object instance
 MyWidget mw = FactoryClass.staticMethod();

then mw would be garbage collected just like any other object that got
instantiated for it.  Preferably, object mw will have its own
housekeeping method that cleans up its particulars so that the same
object that instantiated mw could eliminate it like so (more or less):

mw.cleanUp();
mw = null;

Furthermore, a static method used as a Factory, generally speaking,
should add value (performance, convenience, or otherwise) to the
dispensing of the new object.

Now, at face value, it would seem that all factory objects in
non-distributed application container contexts should be implemented
this way assuming the class is efficient.

As a rule of thumb, would I be correct in suggesting that factory
methods should be static when they serve the broadest utilitarian
purposes and classes should be instantiated for their method access for
more specialized processing purposes?

Finally, when would using this technique be good or bad practice.
After all, this technique seems to violate strict object-oriented
implementation practice.
Andrew McDonagh - 13 May 2005 08:03 GMT
> Alright, I'll buy that.  Let me reiterate what you're saying, just to
> be clear.
[quoted text clipped - 28 lines]
> After all, this technique seems to violate strict object-oriented
> implementation practice.

All java objects are the same in terms of memory management (creation
and removal). It is irrelevant that a static method just happened to be
used to create the object.

The garbage collector is responsible for objects actual destruction. As
a programmer you have no control over when the garbage collector runs.
At best you can ask the CG to run, but it is up to the CG (based on its
own algorithms) whether it will run.

Java objects do not have C++ style destructor. They can override
Object.finalize(), this method MAY be called at sometime if the object
is being CGed, but there is no guarantee. So its better to directly call
your own 'cleanup' method to close File, sockets type resources.

As for static factory methods, they are fine if used sparingly. Its
usually more helpful to have a factory method on an instance of the
factory - then you can override if necessary in a derived factory class.
krasicki - 13 May 2005 21:34 GMT
-snip-

> All java objects are the same in terms of memory management (creation

> and removal). It is irrelevant that a static method just happened to be
> used to create the object.

I want to explore that subject. Take all my arguments as good natured
curiosity.

> The garbage collector is responsible for objects actual destruction. As
> a programmer you have no control over when the garbage collector runs.
> At best you can ask the CG to run, but it is up to the CG (based on its
> own algorithms) whether it will run.

I disagree.  When a Java programmer invokes a System.gc() call it frees
memory to the JVM at the earliest algorithmically determined 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.  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.

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?

Rod Johnson, in J2EE Development without EJB, talks about generational
garbage collection techniques.  Can anyone put static factory methods
into context considering these techniques?

-snip-

> As for static factory methods, they are fine if used sparingly.

Don't you really mean appropriately.  Will using them a lot be worse or
better than using them a little.  What does their proliferation have to
do with it?

> Its
> usually more helpful to have a factory method on an instance of the
> factory - then you can override if necessary in a derived factory class.

Understood.
Daniel Sjöblom - 13 May 2005 22:35 GMT
<snip stuff>
> 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?

It seems that somewhere along the road you have gotten thoroughly
confused about how garbage collection works. As such, it is hard to
answer your question, since you are likely to misinterpret the answer.
Please read this for some basic information about garbage collection:
http://java.sun.com/developer/technicalArticles/ALT/RefObj/

To quote the most relevant parts:

(QUOTE)
The garbage collector's job is to identify objects that are no longer in
use and reclaim the memory. What does it mean for an object to be in use?

    Note: An object is in use if it can be accessed or reached by the
program in its current state.

An executing Java program consists of a set of threads, each of which is
actively executing a set of methods (one having called the next). Each
of these methods can have arguments or local variables that are
references to objects. These references are said to belong to a root set
of references that are immediately accessible to the program. Other
references in the root set include static reference variables defined in
loaded classes, and references registered through the Java Native
Interface (JNI) API.

All objects referenced by this root set of references are said to be
reachable by the program in its current state and must not be collected.
Also, those objects might contain references to still other objects,
which are also reachable, and so on.

All other objects on the heap are considered unreachable, and all
unreachable objects are eligible for garbage collection.
(UNQUOTE)

Note especially the part about /actively executing/ methods. Once a
method returns, any local references in that method are no longer part
of the root set.

Signature

Daniel Sjöblom
Remove _NOSPAM to reply by mail

Ross Bamford - 14 May 2005 04:11 GMT
On Sat, 2005-05-14 at 00:35 +0300, Daniel Sj=B6blom wrote:
> <snip stuff>
> > My question really comes back to a nagging doubt.  Can an object
[quoted text clipped - 39 lines]
> method returns, any local references in that method are no longer part
> of the root set.

I think the source of OPs confusion may be the sentence (fragment)
"Other references in the root set include static reference variables
defined in loaded classes, ...", taken as meaning all reference
variables rather than reference member variables only.

As a more general thing, this confusion is probably an example of the
adage that "a little knowledge is a dangerous thing" (and I mean no
offence by this at all). I am merely suggesting the OP might want to
revisit some of the more fundemental Java concepts before hitting the
metal with BEA references or the more technical J2EE journals.

Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

paul campbell - 13 May 2005 22:41 GMT
> 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?

No.

Returning a value from a method doesnt create a reference (static
or not) so the GC isnt interested in it.

Paul C.

> Rod Johnson, in J2EE Development without EJB, talks about generational
> garbage collection techniques.  Can anyone put static factory methods
[quoted text clipped - 7 lines]
> better than using them a little.  What does their proliferation have to
> do with it?

Use one when it solves a specific problem for you.

Using them indiscriminately makes code harder to read.

Paul C.
krasicki - 14 May 2005 15:01 GMT
> > In other words, does the fact that it has referential roots
> > from a static method make the byproducts of that method all look
[quoted text clipped - 4 lines]
> Returning a value from a method doesnt create a reference (static
> or not) so the GC isnt interested in it.

Paul,

Explain this a bit.

A class that contains a static method does not have to be instantiated.

That method occupies a certain amont of memory in the JVM allocation.
Do all of the POGOs created from that method extend that static
footprint or do they simply get created initially as short-term memory
footprints?

Once I say x = FactoryClass.staticMethodObject();

I have an object that may involve many objects within objects.

When I say, x = null;

I'm hinting to the GC that I'm done with it.  But does the GC look at
it and say, hey, it's part of static memory, leave it there or is the
implicit assumption to return it to free memory.

> > Rod Johnson, in J2EE Development without EJB, talks about generational
> > garbage collection techniques.  Can anyone put static factory methods
[quoted text clipped - 11 lines]
>
> Using them indiscriminately makes code harder to read.

Once again, I must (in good humor) protest.  Couldn't somebody say,
"Hey, if you can read it once, can't you read it twice?  three times?
and so on?  What's so hard to read?

Isn't this more a case of familiarity breeding contempt?
Joona I Palaste - 14 May 2005 16:26 GMT
krasicki <Krasicki@gmail.com> scribbled the following
on comp.lang.java.programmer:
>> > In other words, does the fact that it has referential roots
>> > from a static method make the byproducts of that method all look
[quoted text clipped - 4 lines]
>> Returning a value from a method doesnt create a reference (static
>> or not) so the GC isnt interested in it.

> Paul,

> Explain this a bit.

> A class that contains a static method does not have to be instantiated.

> That method occupies a certain amont of memory in the JVM allocation.
> Do all of the POGOs created from that method extend that static
> footprint or do they simply get created initially as short-term memory
> footprints?

> Once I say x = FactoryClass.staticMethodObject();

> I have an object that may involve many objects within objects.

> When I say, x = null;

> I'm hinting to the GC that I'm done with it.  But does the GC look at
> it and say, hey, it's part of static memory, leave it there or is the
> implicit assumption to return it to free memory.

As far as the GC and memory management are concerned, it makes *NO
DIFFERENCE WHATSOEVER* whether the object was constructed in a static
method or in an instance method. Not even the slightest bit. The
object does not retain any sort of information about which method
created it, unless you explicitly tell it, by calling a method or
setting a member variable. This is true for both objects created in
static methods and ones created in instance methods.

Signature

/-- Joona Palaste (palaste@cc.helsinki.fi) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"You will be given the plague."
  - Montgomery Burns

paul campbell - 25 May 2005 13:50 GMT
>> > In other words, does the fact that it has referential roots
>> > from a static method make the byproducts of that method all look
[quoted text clipped - 15 lines]
> footprint or do they simply get created initially as short-term memory
> footprints?

Your extrapolating from an acute lack of understanding of the fundamentals
of program process memory management - like somone walking into a chemical
research lab and trying second guess what reactions are going to take
place based on the colour of the chemicals being mixed.

You need to go back to basics and study memory managment in modern OS
processes - nevermind trying understand GC.

Paul C.
krasicki - 26 May 2005 02:06 GMT
> >> > In other words, does the fact that it has referential roots
> >> > from a static method make the byproducts of that method all look
[quoted text clipped - 20 lines]
> research lab and trying second guess what reactions are going to take
> place based on the colour of the chemicals being mixed.

You seem to be addressing me.  Everything I've read says that the JVM
manages its own memory management.  Program process management is far
too general for this discussion because we are really talking about
Java.

But the tone of this post is not about solving problems or enlightening
anyone, it's just a slam.  Feel better?

> You need to go back to basics and study memory managment in modern OS
> processes - nevermind trying understand GC.

Spoken like a gentleman and a scholar.
paul campbell - 30 May 2005 18:55 GMT
>> >> > In other words, does the fact that it has referential roots
>> >> > from a static method make the byproducts of that method all look
[quoted text clipped - 26 lines]
> You seem to be addressing me.  Everything I've read says that the JVM
> manages its own memory management.

The VM is a virtual processor executing vitual machine code in
a virtual process which follows the same basic principals of memory
managment as a real process i.e. it has seperate "areas" for executable
code, stack, heap, statics etc. Furthermore java objects and classes
and thier constituent parts are divied up into these areas in much the
same way as real code (say c++) is handled in a real process.

If you undestood this then you would understand why you are so far off
base with your reasoning about VM memory managment.

I say again that you are trying to reason from an unsound foundation
of knowledge - you are trying to understand CG behaviour without
an understanding of more fundamental concepts about how the various
aspects of objects and classes map onto diferent types of memory in
a running process (real or virtual).

>> You need to go back to basics and study memory managment in modern OS
>> processes - nevermind trying understand GC.

I stand by that statement, you arnt going to get any further with your
understanding util you take that advice.

Paul C.
John C. Bollinger - 14 May 2005 00:02 GMT
>>All java objects are the same in terms of memory management (creation
>>and removal). It is irrelevant that a static method just happened to be
[quoted text clipped - 10 lines]
> I disagree.  When a Java programmer invokes a System.gc() call it frees
> memory to the JVM at the earliest algorithmically determined time.

It depends what you mean by that.  System.gc() requests that the GC make
its best effort to reclaim unreachable objects.  Depending on the GC
implementation, that "best effort" could conceivably be no special
action whatsoever.  This is what I believe Andrew was describing.

> 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.

More the *VM's* GC.  I am not aware of any application server that
provides any particular "garbage collection management", nor do I really
see how any could be provided outside tweaking or configuring the VM,
whether the app server wanted to or not.  The article may have been
quite correct, however, in that a program frequently invoking
System.gc() might cause the garbage collector to expend considerably
more effort than it otherwise would do, for no particular gain.

> But let's get even more subtle.  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.

I disagree.  There are cases where it is advantageous to set references
to null, which may allow the GC to clean up an object sooner than it
otherwise would do, but usually it is clearer and easier to simply let
references go out of scope.  It's part of the GC's *job* to recognize
which objects it can reclaim, and nullifying references that are about
to go out of scope or become themselves unreachable anyway just isn't
worth the cost in development time, code clarity, and maintenance.

> 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?

There are no "referential roots".  Java does not know or care about the
origin of a reference.  It cares only about whether the reference, and
thus its referent, is accessible from a live thread.

> Rod Johnson, in J2EE Development without EJB, talks about generational
> garbage collection techniques.  Can anyone put static factory methods
> into context considering these techniques?

Static methods are not in any way special relative to generational
garbage collection.  Generational GC is concerned with how old an object
is, and thus _when_ it was created.  Generation GC, like Java in
general, doesn't care a whit about _how_ it was created.

Signature

John Bollinger
jobollin@indiana.edu

krasicki - 14 May 2005 15:14 GMT
-snip-
> >>The garbage collector is responsible for objects actual destruction.  As
> >>a programmer you have no control over when the garbage collector runs.
[quoted text clipped - 8 lines]
> implementation, that "best effort" could conceivably be no special
> action whatsoever.  This is what I believe Andrew was describing.

I'm suspicious of that idea.  When I read Rod Johnson's assertions
today's JVM machinations are far from do nothing algorithms.  They are
sifting and sorting this stuff for efficiency.

The larger argument is this.  The static method I'm describing is
invoked for every web-based visitor.  The server is rebooted every
night due to performance problems.  I know - hard to believe but I'm
the firefighter not the originator of any of this.

I'm trying to determine if this static factory method might be
contributing to this problem.

> > In
> > fact, I read an IBM or BEA article recently that advised programmers
[quoted text clipped - 5 lines]
> provides any particular "garbage collection management", nor do I really
> see how any could be provided outside tweaking or configuring the VM,

> whether the app server wanted to or not.

Sorry.  I've been overly busy lately so I haven't had time to do more
than type stream of consciousness thoughts.

You are correct about the JVM and GC.  But I think that container
managed issues contribute to this best practice suggestion that
System.gc() not be used.

> The article may have been
> quite correct, however, in that a program frequently invoking
> System.gc() might cause the garbage collector to expend considerably
> more effort than it otherwise would do, for no particular gain.

Yes.

> > But let's get even more subtle.  Hagar, Bulka, and other java stylists
> > recommend explicit cleanup in deeply nested objects.  In other words,
[quoted text clipped - 6 lines]
> otherwise would do, but usually it is clearer and easier to simply let
> references go out of scope.  It's part of the GC's *job* to recognize

> which objects it can reclaim, and nullifying references that are about
> to go out of scope or become themselves unreachable anyway just isn't

> worth the cost in development time, code clarity, and maintenance.

Oh, let's argue this.  The proverbial saying, "as above, so below"
should not be taken so lightly.  I will argue that cleaning up after
oneself is not confusing, nor creates maintenance problems.  It makes
it explicit that no objects are being orphaned.

> > 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
[quoted text clipped - 5 lines]
> origin of a reference.  It cares only about whether the reference, and
> thus its referent, is accessible from a live thread.

But it is not Java we're refering to.  Isn't the GC part of the JVM
functionality?

> > Rod Johnson, in J2EE Development without EJB, talks about generational
> > garbage collection techniques.  Can anyone put static factory methods
[quoted text clipped - 4 lines]
> is, and thus _when_ it was created.  Generation GC, like Java in
> general, doesn't care a whit about _how_ it was created.

Then why would nulling an object provide a hint to the GC that an
object is exhausted?
Ross Bamford - 14 May 2005 18:25 GMT
> -snip-
> > >>The garbage collector is responsible for objects actual
[quoted text clipped - 18 lines]
> today's JVM machinations are far from do nothing algorithms.  They are
> sifting and sorting this stuff for efficiency.

But the point is it *looks* the same. It can be doing whatever it wants
but because the GC is completely encapsulated in the implementation it
must always maintain the various contracts involved. It must be
transparent. For most real purposes, it *is* the same - it's only when
you start getting into JNI (dont!), BCEL, Classloading and so on that
you must consider the *exact* lifecycle of objects and references.

> The larger argument is this.  The static method I'm describing is
> invoked for every web-based visitor.  The server is rebooted every
[quoted text clipped - 3 lines]
> I'm trying to determine if this static factory method might be
> contributing to this problem.

Is this a windoze box? In my experience, this kind of problem is
actually fairly rare with Java. I guess it's purely because the JVM
handles all the mallocs on the programmer's behalf, so it's a simple
thing to ensure memory is not leaked (relatively, from the JVM team's
POV).

This is not to say you *can't* leak memory, just that you *shouldn't*
unless you try (notwithstanding JVM bugs etc).

> > I disagree.  There are cases where it is advantageous to set
> references
[quoted text clipped - 13 lines]
> oneself is not confusing, nor creates maintenance problems.  It makes
> it explicit that no objects are being orphaned.

This comes back to the fundementals of Garbage Collection - an object is
eligable for collection when it is 'orphaned' (this is simplistic but
essentially true). Nulling *references* is a valid technique if you have
need to 'free' objects (e.g. in a long loop) but I am with John on the
general case, in that it's better to let a variable go out of scope.

Look at it this way - when a reference loses scope the JVM throws it
away in effect, leaving the object 'unreachable' and hence eligable for
the bin (next time the JVM goes into the kitchen). So what's the point
of writing "finished with" all over it first? The JVM will still rewrite
the message, which is after all an implementation note to itself (in a
way).

(I know it doesn't quite work when the technical aspects are considered,
so let's not consider the technical aspects for a moment - I believe you
need to step back and view the wood for a while...)

> > > My question really comes back to a nagging doubt.  Can an object
> > > created by a factory class from a static method ever be clean
[quoted text clipped - 12 lines]
> But it is not Java we're refering to.  Isn't the GC part of the JVM
> functionality?

This is a misunderstanding. In Java the term 'referential roots' has no
meaning. The JLS simply uses it to refer to a top-level reference that
is in scope. If an object has no roots in the referential set (I.e. in
scope vars of *all kinds*) then it is, by definition, unreachable.
This is how the whole thing about losing a Map full of objects works,
simply by throwing away the map ref (your root reference in this case).

The GC Implementation is part of the JVM, but Garbage Collection,
referential roots, reference counting and all that predate Java. The
root set is simply a detail of the JVM implementation and has no bearing
on this argument whatsoever.

> > > Rod Johnson, in J2EE Development without EJB, talks about
> generational
[quoted text clipped - 10 lines]
> Then why would nulling an object provide a hint to the GC that an
> object is exhausted?

In the same way that when a reference goes out of scope, the reference
you set to null is removed from that object's reference count when you
make the assignment (or just after I think). Periodically, the JVM runs
through all it's objects (for example), and every one it finds with a
zero reference count (indicating it's not reachable) is eligable for GC.
Note this doesn't necessarily mean they *will* be collected, especially
when we factor in active threads and whatnot, but you get the idea.

I would expect that even internally there is no 'ordinary' way to know
at GC time how or where an object was allocated.

Cheers,
Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

Lee Fesperman - 14 May 2005 20:27 GMT
> > > > My question really comes back to a nagging doubt.  Can an object
> > > > created by a factory class from a static method ever be clean
[quoted text clipped - 15 lines]
> This is how the whole thing about losing a Map full of objects works,
> simply by throwing away the map ref (your root reference in this case).

Ok, in general.

> The GC Implementation is part of the JVM, but Garbage Collection,
> referential roots, reference counting and all that predate Java. The
> root set is simply a detail of the JVM implementation and has no bearing
> on this argument whatsoever.

No modern JVM/GC uses reference counting.

> > > > Rod Johnson, in J2EE Development without EJB, talks about
> > > > generational garbage collection techniques.  Can anyone put
[quoted text clipped - 15 lines]
> Note this doesn't necessarily mean they *will* be collected, especially
> when we factor in active threads and whatnot, but you get the idea.

Again, reference counting is not the way GC works, today; it works purely by
reachability analysis. Reference counting can produce 'orphans'. I think you should
educate yourself better because you are adding to the confusion in this thread.

Signature

Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
==============================================================
* The Ultimate DBMS is here!
* FirstSQL/J Object/Relational DBMS  (http://www.firstsql.com)

Ross Bamford - 14 May 2005 21:03 GMT
> No modern JVM/GC uses reference counting.

> Again, reference counting is not the way GC works, today; it works purely by
> reachability analysis. Reference counting can produce 'orphans'. I think you should
> educate yourself better because you are adding to the confusion in this thread.

I'd argue that a lot more confusion comes from messages highlighting
out-of-date facts that are actually irrelevant to the discussion. Okay,
so reference counting isn't used any more - the point is, I don't need
to know or care from a development point of view, because it 'just
works' regardless of where or how I instantiate new objects.

In any case the intent is the same - an object unreachable object has no
references. Whether you counted them, tracked them, or registered
details in a database every time one was used (;)), the point is that
you know, in the, end, that there are none.

However, I do apologise for my error - I must admit I am only really an
enthusiast when it comes to the JVMs deep internals.

Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

Lee Fesperman - 14 May 2005 23:06 GMT
> > No modern JVM/GC uses reference counting.
>
[quoted text clipped - 7 lines]
> to know or care from a development point of view, because it 'just
> works' regardless of where or how I instantiate new objects.

Ok, that's true enough in terms of most of the confusion on this thread and in terms of
where or how you instantiate new objects, but ...

> In any case the intent is the same - an object unreachable object has no
> references. Whether you counted them, tracked them, or registered
> details in a database every time one was used (;)), the point is that
> you know, in the, end, that there are none.

The problem with reference counting (and, probably, the other methods you mentioned) is
circular references. In a circular reference, 2 or more objects reference each other, so
even though they are not reachable from live code, they don't have a reference count of
zero. These could be called orphans, which the OP did mention, thus I didn't want you to
cause him concern over that issue.

Signature

Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
==============================================================
* The Ultimate DBMS is here!
* FirstSQL/J Object/Relational DBMS  (http://www.firstsql.com)

Ross Bamford - 15 May 2005 02:19 GMT
> > > No modern JVM/GC uses reference counting.
> >
[quoted text clipped - 21 lines]
> zero. These could be called orphans, which the OP did mention, thus I didn't want you to
> cause him concern over that issue.

Which, then, is where the fact that even if an object has one or more
actual references, if it cannot be referenced from the 'root set' (see
earlier) that fact is discounted (since it isn't reachable). Of course,
it makes sense. I was even contradicting myself ;)

I wonder if you could recommend a good link for a (quick) knowledge
update?

Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

Daniel Sjöblom - 14 May 2005 21:27 GMT
> In the same way that when a reference goes out of scope, the reference
> you set to null is removed from that object's reference count when you
[quoted text clipped - 3 lines]
> Note this doesn't necessarily mean they *will* be collected, especially
> when we factor in active threads and whatnot, but you get the idea.

I'm not aware of any JVMs that use reference counting for GC. The
problem with reference counting is that objects that circularily point
to each other will be considered live, even though there is no way to
reach them from 'the outside' so to speak. I'll explain a bit further
about the approach normally taken in JVMs.

The basic idea in most JVMs is to keep track of which objects at time A
could possibly be accessed by the program, with the help of something
called reachability analysis. If we consider a simplified JVM with no
static variables and no JNI, and only one thread running, the program at
a point A looks something like this on the stack:

-------------
| main method
-------------
| method a
-------------
| method b
-------------
| method c    <- Currently executing method c.
-------------

Where the method call chain is main -> a -> b -> c. Suppose we suspend
the program at this point, and wish to compute the set of all currently
reachable objects. How do we do this? If we do some preparation, it is
not too hard. Before we run any method, we calculate a garbage
collection map for the method. This will simply be a data structure that
contains information about which local variables in the method can
contain references to objects. For instance, it might look like this (*):

public class GCMap
{
    int[] framePointerOffsets;
}

where framePointerOffsets contains the adresses (relative to the
framepointer) of local variables that contain references.

So, now all we need to do this is walk the stack backwards and with the
help of the garbage collection maps add all the references currently
contained in the local variables of each method to a set, which we will
call the root set. The code could like this:

Set rootSet = empty

for stackframe in stack
    for offset in framePointerOffsets in GCMap of method at stackframe
        rootSet = rootSet U (value at (framePointer + offset))

So now we have our root set. The last thing we need to do is follow all
of the references in the root set to find other live references and from
those references go to yet others and so on. This can be done with a
standard graph search. If some object is not reachable from the root set
of references, it cannot possibly be accessed by the program anymore,
and as such is garbage which can be collected.

This is a simplified explanation of a very simple reachability analysis,
in reality things are more complicated (and there are various
alternative procedures for achieving the same goals). This example
should however also explain why references may need to be 'nulled' at
times. In the gathering of references to the root set, we are only
considering the state of the program at point A, and ignoring anything
that may happen in the future. For instance, we may have a reference in
a local variable at point A which is never read (never used) again in
the future. But our analyzer does not know this! Hence we (as
programmers) may need to manually 'null' references in certain methods,
when we know that a reference points to an object we will not use anymore.

* we assume all local variables are on the stack

-------------
Signature

Daniel Sjöblom
Remove _NOSPAM to reply by mail

Laurent Bossavit - 15 May 2005 09:23 GMT
Krasicki,

> The larger argument is this.  The static method I'm describing is
> invoked for every web-based visitor.  The server is rebooted every
> night due to performance problems. [...] I'm trying to determine
> if this static factory method might be contributing to this problem.

It's not; or rather, the sole fact that it's static is not a sufficient
or a necessary condition for this kind of problem to arise. It's
irrelevant. A thread's stack is the root of all object references,
together with static instance *variables*. The keyword static means
something different altogether for methods - unfortunate overloading of
the name. At any rate, a stack frame for a static method is not treated
differently from a stack frame of a regular method.

Get yourself a copy of OptimizeIt or similar. It's possible to debug
such problems "statically" - by which I mean through the sole means of
reading the source code; I've done it a few times. A profiler is a
quicker way, and it will locate the problem even if it's not due to your
own code but rather to some third-party code.

Interaction between the language and the GC should be covered by the
Java Language Specification - have you read that ? Section 12.6 covers
object finalization.

See also:

http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.h
tml

Laurent
krasicki - 16 May 2005 02:59 GMT
> Krasicki,
>
[quoted text clipped - 10 lines]
> the name. At any rate, a stack frame for a static method is not treated
> differently from a stack frame of a regular method.

Bingo - best answer.  Let's repeat it, *The keyword static means
> something different altogether for methods - unfortunate overloading of
> the name.*   This is what confused me most and something I have never
seen said in a technical discussion.

> Get yourself a copy of OptimizeIt or similar. It's possible to debug
> such problems "statically" - by which I mean through the sole means of
> reading the source code; I've done it a few times. A profiler is a
> quicker way, and it will locate the problem even if it's not due to your
> own code but rather to some third-party code.

Yes, good advice for shops that take advice.

> Interaction between the language and the GC should be covered by the
> Java Language Specification - have you read that ? Section 12.6 covers
> object finalization.
>
> See also:

http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.h
> tml

Thanks.  Yeah I read a lot but it's overwhwelming and everything gets
dated very quickly.  I had not run across this before and being someone
who likes OO programming I don't look for workarounds - hence a
blindspot with this subject.
Laurent Bossavit - 16 May 2005 07:08 GMT
Krasicki,

> Yes, good advice for shops that take advice.

There you have it - the Consultant's Ultimate Frustration. Pretty much
the same as the architect's, right ?

Laurent
Rich MacDonald - 17 May 2005 05:10 GMT
"krasicki" <Krasicki@gmail.com> wrote in news:1116208763.211291.313660
@o13g2000cwo.googlegroups.com:

> Bingo - best answer.  Let's repeat it, *The keyword static means
>> something different altogether for methods - unfortunate overloading
> of
>> the name.*   This is what confused me most and something I have never
> seen said in a technical discussion.

Never could have guessed that was what was hanging you up. Prior language
hangover? Yeah, I've just been reading this thinking "this is obvious, he
can't be serious, but he needs a shakeout, so go with the flow."

With my Smalltalk background, a static method is just another place where
things can happen ---> the *same* happenings that all methods follow. Is an
object created? Does something point to it when the method is complete?
Then it follows the same rules as always. Nothing to it. Don't
overcomplicate the thought process.

> http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.h
>> tml
[quoted text clipped - 3 lines]
> who likes OO programming I don't look for workarounds - hence a
> blindspot with this subject.

Although an aside at this point, the object reference nullifying is a
workaround, and hopefully an old wive's tale that's no longer relevant.
krasicki - 18 May 2005 03:21 GMT
> "krasicki" <Krasicki@gmail.com> wrote in news:1116208763.211291.313660
> @o13g2000cwo.googlegroups.com:
[quoted text clipped - 8 lines]
> hangover? Yeah, I've just been reading this thinking "this is obvious, he
> can't be serious, but he needs a shakeout, so go with the flow."

No, it was not 'hanging me up' but you're missing a back story context.
The code I was evaluating came with a requirements document that was
really a narrative functional specification.  And it said, more or
less, "I'm using this technique to save memory."!  That completely
turned me around and ignited a search for such effect and when none was
found, then this thread.

I'm smart enough to know I may not know and dumb enough to ask.  My
hunch that this had nothing to do with saving memory I think is correct
but I was unsure of the scope and effect of the static keyword on the
factory method byproducts.

> With my Smalltalk background, a static method is just another place where
> things can happen ---> the *same* happenings that all methods follow. Is an
> object created? Does something point to it when the method is complete?
> Then it follows the same rules as always. Nothing to it. Don't
> overcomplicate the thought process.

http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html

This link is a bit crusty so I looked further.  Check this out;

http://today.java.net/pub/a/today/2003/12/30/staticsSQ1.html

> Although an aside at this point, the object reference nullifying is a

> workaround, and hopefully an old wive's tale that's no longer relevant.

Indeed.  Take a look at what some gamers think of my old wives
technique;

http://www.javaspecialists.co.za/archive/Issue060.html
Virgil Green - 19 May 2005 22:18 GMT
> Krasicki,
>
[quoted text clipped - 11 lines]
> method is not treated differently from a stack frame of a regular
> method.

I'm curious to know how you think the keyword static is different for
variables and methods. I've always taken it to mean the same thing for
both... members of a class rather than an instance of a class (or, an
object, if you will).

Anyway, I've read most of this thread and it seems that the entire point
that was missed by the OP was that objects are always created in the heap
and only references are found on the stack (flameproof suit on in case I've
oversimplified). When a static method creates an object it may retain a
reference to it only as long as any reference variables stay within scope on
the stack. There isn't any memory associated with the static method that
"grows" as new objects are created. The static method's memory could be said
to be the stack frame(s) created when the method is invoked... there are no
objects in that memory and the references in that memory go out of scope
when the stack frame is "popped" off the stack.

Anyway, oversimplification, I'm sure -- but I hope it helped rather than
hurt the discussion.

Signature

Virgil

krasicki - 26 May 2005 02:19 GMT
Virgil,

I missed your post earlier.  Thanks for the reply.  At the time I was
evaluating some very suspicious code and my last excursion into such
issues was a number of years ago.   The author in question almost
exclusively uses static methods and claimed to save memory. I began
looking for proof this was true (I am open to the idea that things
change and maybe there's something new going on here).

The current environment I'm in is very basic but I was tryinng to
remember Jprobe documentation and some other dated techniques about
memory management. A few years ago, nulling deep objects was
recommended and that idea still exists if you reference some f the
material I link to elsewhere.  Today the practice is senseless but I
didn't know that for sure going into this discussion.

There remains an antiseptic idea that objects cannot be 'orphaned' in
memory but I don't know if that's absolutely true.  Again, that's why I
thought exploring these ideas in one place made sense.

Your contribution added value. Thanks.
Laurent Bossavit - 26 May 2005 07:05 GMT
Krasicki,

> There remains an antiseptic idea that objects cannot be 'orphaned' in
> memory but I don't know if that's absolutely true.

One more enlightening read:
 http://www.szegedi.org/articles/memleak.html

Laurent
Andrew McDonagh - 14 May 2005 19:59 GMT
> -snip-
>
[quoted text clipped - 8 lines]
> 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.

>>The garbage collector is responsible for objects actual destruction.
>
[quoted text clipped - 12 lines]
> 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-
>
>>As for static factory methods, they are fine if used sparingly.
>
> 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.

>>Its
>>usually more helpful to have a factory method on an instance of the
[quoted text clipped - 3 lines]
>
> Understood.
Ross Bamford - 14 May 2005 20:51 GMT
> 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.

In fact, I would have preferred a strategy where no GC 'suggestion' is
offered at all in the standard Runtime, and integrators must insert
custom implementation (perhaps of a specific GCManager so as not to
expose too much) to get any kind of handle on the management.

I've never liked 'go do what you do, or don't, I don't care' methods,
especially when there may be a dramatic performance hit, or even VM-wide
freeze-up for a second or two in a busy system... (Witness numerous
Swing apps where the fashion is to do System.gc() on certain menu
commands).

Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

krasicki - 16 May 2005 03:20 GMT
> > -snip- -all good comments -
>
[quoted text clipped - 9 lines]
>
> Other than that, try to prefer an instance method of an object.

- snip -

Yes.  This is really the crux of the argument.  This is procedural
stuff poking its way into OO territory and i always get the feeling
that people doing it get a secret pleasure out of it - like kicking a
vending machine.
Ross Bamford - 13 May 2005 12:39 GMT
> As a rule of thumb, would I be correct in suggesting that factory
> methods should be static when they serve the broadest utilitarian
[quoted text clipped - 4 lines]
> After all, this technique seems to violate strict object-oriented
> implementation practice.

Factory methods are great where you want a singleton:

public class ServiceProvider
{
 private static final ServiceProvider prov =
   new ServiceProvider(class.getResourceAsStream("sp.xml"));

 private ServiceProvider(InputStream XML) {
   // ... Configure from XML ...
 }

 public Degigitator doService(Rerulurator r) {
   // ... service according to config ...
 }

 // Factory
 public static ServiceProvider getInstance() {
   return prov;
 }
}

This is ideal for stuff you want global, since there will be only one
instance per JVM, and you can get it from anywhere:

myDegig = ServiceProvider.getInstance().doService(myRulurator));

If your needs are more complex, you could have a static factory that
creates instance factories with a certain configuration. In this
situation I often define an abstract class as the factory 'interface',
and provide on that the static factory.

Handy uses are many: SPI, Registry, logging (in small apps), etc, etc,
etc. It does require a little more consideration of the runtime
lifecycle of the JVM, and there are one or two nasty gotchas (as always)
but generally it's a useful technique (that seems to be going out of
fashion now in favour of context-scoped 'singletons').

Cheers,
Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

Wibble - 14 May 2005 00:27 GMT
Stop looking for stupid rules and do what makes sense.
The rules I use when programming java are:

You arent gonna need it.

Do the simplest thing that can possibly work.

(Yeah, I stole them from Beck)

If you NEED a factory for a reason, create one, otherwise
dont.  If you dont understand why you need one, you dont
need one.

>>As a rule of thumb, would I be correct in suggesting that factory
>>methods should be static when they serve the broadest utilitarian
[quoted text clipped - 44 lines]
> Cheers,
> Ross
Ross Bamford - 14 May 2005 04:01 GMT
> <fixed toppost>

> >>As a rule of thumb, would I be correct in suggesting that factory
> >>methods should be static when they serve the broadest utilitarian
[quoted text clipped - 57 lines]
> dont.  If you dont understand why you need one, you dont
> need one.

You know, you can actually do most stuff by stringing commands together
with a shell. That way, you don't need to worry about the bytecode
interpreter, runtime, factories, classes, instantiation, oop, methods,
or any of that other stupid advanced crap.

Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

Andrew McDonagh - 14 May 2005 20:10 GMT
> I had never run into this before but have recently encountered code
> that is something like:
[quoted text clipped - 20 lines]
> Disclaimer:  YES,YES,YES - I know, I know... but take it for what it's
> worth.

Actually just realised something that may help you - or confuse you
completely...  ;-)

Seeing as the only way to start a java application is via a class's
'main method.

class HelloWorldApp {

    public static void main(String[] args) {
       Message m = new Message();
       m.show();
    }
}

class Message {

    public void show() {
       String theMessage = "Hello world";
       System.out.println(theMessage);
}

Seeing as this is the case, just about every single object created by
the application, will have some relationship to the static main method.

In the case above, the message object referenced by 'm', has been
created by the 'main' method.  It in turns creates the String object
referenced by 'theMessage'.

if it was a GUI app, then we could have created a dialog, with various
components inside the 'show()' method, and so the tree of related
objects would grow even larger.

Does this help show that creating objects and static methods have no
baring upon each other and so how the GC works with those objects?
Nick Malik [Microsoft] - 15 May 2005 08:23 GMT
Has it occurred to you that the problem isn't the return of the newly
created object, but perhaps it's in the section you labeled 'yada yada'?

> public static MyWidget staticMethod()  {
> // yada yada
> return new MyWidgetObject();
> }

Caveat: I'm not a Java developer.  If I say something goofy, please forgive.

Are you creating other things, or manipulating static variables in your
class (or calling another static method on this or another class that
manipulates heap memory) during this 'yada yada'?  The problem may be that
these memory locations are shared between threads.  Could you be running
into concurrency issues where you have referenced a shared value without
considering the thread-safety of these values?

Signature

--- Nick Malik [Microsoft]
   MCSD, CFPS, Certified Scrummaster
   http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
  I do not answer questions on behalf of my employer.  I'm just a
programmer helping programmers.
--

krasicki - 16 May 2005 02:46 GMT
Nick,

Sorry, no hidden gotchas.  I was on my way to my son's Pony League
baseball game and was being as straightforward and brief as could be.

However, much of the surrounding code is ugly in a juvenile way which
is why I questioned this technique.  I'm guessing whoever wrote the
stuff remembered a shortcut but didn't pay attention to elementary
things like if-then-else (I have multiple if statements on after
another (lots 'o them) in a while loop.

This onion would make you all cry.

Thanks, Nick - I hear you and you're correct in asking but what
prompted my questrion was my inability to find good literature on this
specific subject.  I'm being intentionally belligerent to shake it all
out well so that others looking for a comprehensive treatment might get
it here.

Everyone responding has been great and the thread, IMO, is worth a
read.

cheers,

Frank

> Has it occurred to you that the problem isn't the return of the newly

> created object, but perhaps it's in the section you labeled 'yada yada'?
>
[quoted text clipped - 7 lines]
> Are you creating other things, or manipulating static variables in your
> class (or calling another static method on this or another class that

> manipulates heap memory) during this 'yada yada'?  The problem may be that
> these memory locations are shared between threads.  Could you be running
[quoted text clipped - 11 lines]
> programmer helping programmers.
> --
Tony Morris - 15 May 2005 09:53 GMT
This is the correct way to expose construction of objects.
Non-private constructors violate encapsulation.
If only this very fundamental, simple and obvious concept was taught from
the beginning.
Book containing explanation pending...

Signature

Tony Morris
Software Engineer, IBM Australia.
BInfTech, SCJP 1.4, SCJP 5.0, SCJD

http://www.jtiger.org/ JTiger Unit Test Framework for Java
http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
http://xdweb.net/~dibblego/

krasicki - 16 May 2005 02:35 GMT
> This is the correct way to expose construction of objects.

Don't you mean 'A' correct way.

> Non-private constructors violate encapsulation.

I'm not sure where you're going here.

> If only this very fundamental, simple and obvious concept was taught from
> the beginning.
> Book containing explanation pending...

Tony, you're awfully sparse on words here.

> --
> Tony Morris
[quoted text clipped - 4 lines]
> http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
> http://xdweb.net/~dibblego/
Tony Morris - 16 May 2005 13:12 GMT
> > This is the correct way to expose construction of objects.
>
> Don't you mean 'A' correct way.

No.

> > Non-private constructors violate encapsulation.
>
> I'm not sure where you're going here.

Think about it - it's not a secret (that is, I didn't dream it up - it's a
fundamental fact known to all practising purists).

> > If only this very fundamental, simple and obvious concept was taught
> from
> > the beginning.
> > Book containing explanation pending...
>
> Tony, you're awfully sparse on words here.

I intended only to provoke thought on behalf of the reader, not write the
book.

> > --
> > Tony Morris
[quoted text clipped - 4 lines]
> > http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
> > http://xdweb.net/~dibblego/

Signature

Tony Morris
Software Engineer, IBM Australia.
BInfTech, SCJP 1.4, SCJP 5.0, SCJD

http://www.jtiger.org/ JTiger Unit Test Framework for Java
http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
http://xdweb.net/~dibblego/

Tor Iver Wilhelmsen - 16 May 2005 19:07 GMT
> Think about it - it's not a secret (that is, I didn't dream it up - it's a
> fundamental fact known to all practising purists).

Since a lot of programmers disagree with you (ie. they think that
constructors can be non-private), calling it a "fundamental fact"
makes you look like an arrogant snob.
Tony Morris - 17 May 2005 09:37 GMT
> > Think about it - it's not a secret (that is, I didn't dream it up - it's a
> > fundamental fact known to all practising purists).
>
> Since a lot of programmers disagree with you (ie. they think that
> constructors can be non-private), calling it a "fundamental fact"
> makes you look like an arrogant snob.

Perhaps so, but I have no qualms with that - the truth is of far more
importance than mere ego attacks.
Copernicus looked like one of those too, before the Earth orbitted the Sun.

Signature

Tony Morris
Software Engineer, IBM Australia.
BInfTech, SCJP 1.4, SCJP 5.0, SCJD

http://www.jtiger.org/ JTiger Unit Test Framework for Java
http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
http://xdweb.net/~dibblego/

Rich MacDonald - 17 May 2005 23:06 GMT
> practising purists

Mutually incompatible.
Joona I Palaste - 16 May 2005 21:50 GMT
Tony Morris <not@telling.you> scribbled the following
on comp.lang.java.programmer:
> This is the correct way to expose construction of objects.
> Non-private constructors violate encapsulation.
> If only this very fundamental, simple and obvious concept was taught from
> the beginning.
> Book containing explanation pending...

I'd love to see that book of yours. I know something about Java, but I
can't think of any useful way to create new objects in Java without using
non-private constructors at some point. Unless you want to use the
static factory pattern in *every* class, which I find ugly.

Signature

/-- Joona Palaste (palaste@cc.helsinki.fi) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"I am lying."
  - Anon

Tony Morris - 17 May 2005 09:42 GMT
> Tony Morris <not@telling.you> scribbled the following
> on comp.lang.java.programmer:
[quoted text clipped - 8 lines]
> non-private constructors at some point. Unless you want to use the
> static factory pattern in *every* class, which I find ugly.

The book is currently a set of scribble notes in a A4 pad.
I make no promises, but I do beg of you, please think about it some more -
it is blatantly obvious to any "practising purist".
That is to say, ask anyone else who is also part of this minority group and
they might provide a peek into the persecptive I speak of.
I dare not for fear of undermining the entire point, hence I intend
(actually, I 'hope') to cover it in full some day.
An example of undermining the points is the article written by Holub titled
'Why extends is evil'.
Any practising purist also knows that concrete inheritance implies a flawed
design (yes, always), but Holub makes the point in a horrible way.
I have refuted this article in somewhat minor detail (again, due to the
aforementioned apprehension) here:
http://www.jtiger.org/articles/why-extends-is-not-evil.html

Signature

Tony Morris
Software Engineer, IBM Australia.
BInfTech, SCJP 1.4, SCJP 5.0, SCJD

http://www.jtiger.org/ JTiger Unit Test Framework for Java
http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
http://xdweb.net/~dibblego/

Ross Bamford - 17 May 2005 16:50 GMT
> > Tony Morris <not@telling.you> scribbled the following
> > on comp.lang.java.programmer:
[quoted text clipped - 24 lines]
> aforementioned apprehension) here:
> http://www.jtiger.org/articles/why-extends-is-not-evil.html

Nice one Tony :) The original /is/ somewhat inflammatory ;) Out of
interest, have a quick look at some of the dependency injection stuff
around now, which I think has the potential to remedy the situation if
used properly. Particularly with respect to implementation hiding and
encapsulation. The goal for my current project is to be based entirely
around interfaces, with implementations being dynamically registered and
selected from those available to fit the need of another.

The only thing I would say is that final classes, while preventing
concrete inheritance, also prevents lots of clever stuff like dynamic
proxy classes and stuff, which helps make the above possible. Another
solution might be to simply remove it from the language, along with
making 'extends' illegal on classes. ;)

Cheers,
Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

Tony Morris - 17 May 2005 22:16 GMT
> > > Tony Morris <not@telling.you> scribbled the following
> > > on comp.lang.java.programmer:
[quoted text clipped - 41 lines]
> Cheers,
> Ross

Indeed, hence for some frameworks, such as Hibernate that use dynamic
proxying, the best I can do is declare the class non-final and declare all
methods final (including, unfortunately, those of java.lang.Object). I agree
that dependency injection is one solution, though I'm not prepared to say
that it is the solution. A language fix would solve it, and the abolishment
of extends on concrete types is certainly better than my suggested
'convention', but even so, that's a workaround and you are forever tied to
concrete inheritance (java.lang.Object). Only a breaking on reverse
compatibility will ultimately fix it (a new language perhaps?)

Here are some thoughts:
- Swing is the most difficult of APIs to write unit tests for, and it is
also the core API that has the strongest dependancy on concrete inheritance.
- Whever you cannot achieve 100% coverage of your code due to test, it is
always because of concrete inheritance. That is to say, without concrete
inheritance, you can always achieve 100% coverage. If you cannot achieve
100% coverage, then why does the code exist? The test code is, after all,
the client.
- JTiger (http://www.jtiger.org/) achieves 100% class and 100% method
coverage, however, outright 100% coverage cannot be achieved in cases where
a third  party dependancy exists since concrete inheritance is used e.g. Ant
task, JavaBeans, Java exceptions (all three of these mandate concrete
inheritance directly or indirectly). In all other cases, 100% coverage is
achieved. It is in these circumstance only where a trade-off is justified
(e.g. shall I rewrite Ant/JavaBeans/the Java language properly, or concede
and use concrete inheritance and expose a constructor in my types? I chose
the latter for obvious reasons). JTiger declares all classes final (hiding
the dependancy on concrete inheritance, but not exposing it itself).

I just realised I have gone from "constructors violate encapsulation to
concrete inheritance violates encapsulation", but the two assertions are
intrinsically related.
Still, what do you mean inflammatory? What exactly?

Tony Morris
Software Engineer, IBM Australia.
BInfTech, SCJP 1.4, SCJP 5.0, SCJD

http://www.jtiger.org/ JTiger Unit Test Framework for Java
http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
http://xdweb.net/~dibblego/
Lee Fesperman - 18 May 2005 20:16 GMT
> > > > Tony Morris <not@telling.you> scribbled the following
> > > > on comp.lang.java.programmer:
[quoted text clipped - 59 lines]
> > Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
> > http://www.roscopec0.f9.co.uk/ + info@the.website.domain

--- retained for reasons explained below ---

> - Whever you cannot achieve 100% coverage of your code due to test, it is
> always because of concrete inheritance. That is to say, without concrete
> inheritance, you can always achieve 100% coverage. If you cannot achieve
> 100% coverage, then why does the code exist? The test code is, after all,
> the client.

I can't believe you're claiming that one can have 100% test coverage except for the most
trivial of applications. Then, you claim that concrete inheritance is the only reason
100% can't be achieved. What about multithreading, customer input, GUI complications?

> - JTiger (http://www.jtiger.org/) achieves 100% class and 100% method
> coverage, however, outright 100% coverage cannot be achieved in cases where
[quoted text clipped - 6 lines]
> the latter for obvious reasons). JTiger declares all classes final (hiding
> the dependancy on concrete inheritance, but not exposing it itself).

Oh, now I see, you're touting unit test software. I think everyone will need to take
your pronouncements with a grain of salt.

> I just realised I have gone from "constructors violate encapsulation to
> concrete inheritance violates encapsulation", but the two assertions are
> intrinsically related.
> Still, what do you mean inflammatory? What exactly?

While there is some general agreement that concrete inheritance can be problematic, you
seem to be the only one claiming it is always wrong. I'm afraid your supporting comments
on that tack are vague. Get off your soapbox and write your book ;^)

BTW, you've also fallen back into bad quoting style. Please trim signatures when you
quote, please.

Signature

Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
==============================================================
* The Ultimate DBMS is here!
* FirstSQL/J Object/Relational DBMS  (http://www.firstsql.com)

krasicki - 18 May 2005 04:11 GMT
> Tony Morris <not@telling.you> scribbled the following
> on comp.lang.java.programmer:
[quoted text clipped - 8 lines]
> non-private constructors at some point. Unless you want to use the
> static factory pattern in *every* class, which I find ugly.

Joona, here's the chapter he's looking for;

http://today.java.net/pub/a/today/2005/04/14/dependency.html
Tony Morris - 18 May 2005 06:04 GMT
> > Tony Morris <not@telling.you> scribbled the following
> > on comp.lang.java.programmer:
[quoted text clipped - 15 lines]
>
> http://today.java.net/pub/a/today/2005/04/14/dependency.html

At first glance, that looks to me like the strategy design pattern
reiteratively re-explained explained again.
This is related to the fundamental rule that the use of Java switch/case can
never be justified (no, not even in 1.5) :) Should I shut up or give reasons
why I don't want to justify that too? The article provides a half-arsed
explanation - the audience should get the gist.

Signature

Tony Morris
Software Engineer, IBM Australia.
BInfTech, SCJP 1.4, SCJP 5.0, SCJD

http://www.jtiger.org/ JTiger Unit Test Framework for Java
http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
http://xdweb.net/~dibblego/

John C. Bollinger - 17 May 2005 18:26 GMT
> This is the correct way to expose construction of objects.
> Non-private constructors violate encapsulation.
> If only this very fundamental, simple and obvious concept was taught from
> the beginning.

This assertion is certainly simple to _express_, but it's correctness is
not obvious, at least to me.  That being the case, I sincerely doubt
whether it is simple to explain or justify.

> Book containing explanation pending...

That book seems always to be pending.  It's the same one, I presume,
where you are going to discuss why you say all classes should be either
abstract or final?  I at least have less trouble imagining possible
arguments for that one.

Any way around, it adds nothing useful to the discussion to make
controversial assertions and then duck all attempts to engage you in any
debate about them.  Appeal to the authority of a nonexistent book in no
way supports your claims.  When the book appears, however, let us know.

Signature

John Bollinger
jobollin@indiana.edu

Tony Morris - 17 May 2005 22:20 GMT
> > This is the correct way to expose construction of objects.
> > Non-private constructors violate encapsulation.
[quoted text clipped - 11 lines]
> abstract or final?  I at least have less trouble imagining possible
> arguments for that one.

No, always final.

> Any way around, it adds nothing useful to the discussion to make
> controversial assertions and then duck all attempts to engage you in any
> debate about them.  Appeal to the authority of a nonexistent book in no
> way supports your claims.  When the book appears, however, let us know.

Agreed, I try to shut up, but it slips out every now and then and goes far
beyond the intended course.
Still, I maintain that if you (or anyone) has the right to suggest that, for
example, "you should inherit from this class" on no sound basis (which I
claim does not exist even if it were attempted), I also maintain the right
to say, "no, do not inherit from this class" (on a basis that I claim exists
and I *know* exists without doubt - at least in my mind).

Signature

Tony Morris
Software Engineer, IBM Australia.
BInfTech, SCJP 1.4, SCJP 5.0, SCJD

http://www.jtiger.org/ JTiger Unit Test Framework for Java
http://qa.jtiger.org/ Java Q&A (FAQ, Trivia)
http://xdweb.net/~dibblego/

Dale King - 18 May 2005 05:07 GMT
>>>This is the correct way to expose construction of objects.
>>>Non-private constructors violate encapsulation.
[quoted text clipped - 24 lines]
> Agreed, I try to shut up, but it slips out every now and then and goes far
> beyond the intended course.

Well, saying that it is "obvious" when it is not obvious to those here
is not an effective way of shutting up. You basically are insulting
anyone that disagrees with you.

> Still, I maintain that if you (or anyone) has the right to suggest that, for
> example, "you should inherit from this class" on no sound basis (which I
> claim does not exist even if it were attempted), I also maintain the right
> to say, "no, do not inherit from this class" (on a basis that I claim exists
> and I *know* exists without doubt - at least in my mind).

It seems to me that you have two assertions that you are trying to merge
into one and I fail to see how they are related. The assertions I see are:

- Concrete inheritance is evil
- Constructors should be private

Even if one agreed with the first one the second one does not follow
from the first. Even with no concrete inheritance you still need a way
to create concrete instances.

For the first I would agree that concrete inheritance is quite often
abused and should be used less that it is, I do not agree that it is
always evil. For one thing every class in Java uses concrete
inheritance. Every object inherits some concrete implementations from
Object.

I find very little justification for your second assertion and you have
offered none.
Signature

 Dale King

Tony Morris - 18 May 2005 05:59 GMT
> >>>This is the correct way to expose construction of objects.
> >>>Non-private constructors violate encapsulation.
[quoted text clipped - 28 lines]
> is not an effective way of shutting up. You basically are insulting
> anyone that disagrees with you.

I'm assuming that the doctrine is merely being iterated as fundamental fact
without any thought.
With a completely open mind, it is obvious, at least, to me. No insult is
intended.

> > Still, I maintain that if you (or anyone) has the right to suggest that, for
> > example, "you should inherit from this class" on no sound basis (which I
[quoted text clipped - 11 lines]
> from the first. Even with no concrete inheritance you still need a way
> to create concrete instances.

They are very much related, but again, I'm being torn between 'shutting up'
and writing a book chapter.
I dare not fall somewhere in between for fear of undermining the truth and
potentially confusing an audience.

> For the first I would agree that concrete inheritance is quite often
> abused and should be used less that it is, I do not agree that it is
> always evil. For one thing every class in Java uses concrete
> inheritance. Every object inherits some concrete implementations from
> Object.

Yes, Java is intrincisally flawed. I intend to offer alternatives to
concrete inheritance, including the special case of java.lang.Object (which
ties the language spec., not just the API spec., to concrete inheritance).
The only justification for concrete inheritance is where a third party
dependancy exists - should you reimplement that dependancy (in this case,
the Java programming language) or concede to the brokenness? In cases where
you concede, I intend to provide a neat solution (isolating the brokenness).
You would concede in some cases because of a trade-off; sure, reimplementing
Java is extreme and reality is reality. It certainly pays to acknowledge
that it exists though. For the case of concrete inheritance without a third
party depend