You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Marc Schier <MS...@infogation.com> on 2002/06/07 17:32:16 UTC

RE: [Design] ContainerManager is under fire--let's find the best resolution

Hi all,

I totally agree with the facts below.  Java's GC is just a helping hand, but
it is not meant to be a solution for memory leaks.  The developer has to be
smart enough to make GC work right.  IMO, using a framework like Avalon
already makes it overly easy to keep an overview of objects obtained so it
is easy for a relatively dumb developer (like me) to release these objects
as well.

>From my point of view there are only two ways to use a component...

1. Quick lookup/service/release sequence with release in a finally block.
2. Obtain component, storing component, releasing component back to the
manager in dispose lifecycle method.

What other ways to obtain and release a component are there that could
confuse a developer so that he forgets the release part?  
(I admit that most of the developers in my company first intuetivly called
dispose() on the component itself instead of returning the component to the
manager.  This is obviously not optimal in the current design.)

But then, if you learn these patterns, you should be able to develop good
components without forgetting to release the component.  I do not understand
it, it is not like you would have to keep a reference count or so.  You just
call release at the right time.  As a developer I really wanna keep control
over the way components are created and released and I can only have this
control if I do it myself in that I return the component to the place where
I obtained it from.  Exactly that was what drew me to Avalon, not that
everything is transparent for me.  

IMO, the best design comes from Berin's initial proposal, which is the
Token/Request/Prototype implementation including a release on the token.
This is the cleanest way to work with the CM.  The code inside the component
will be much nicer and cleaner and it would also allow the component to
obtain a reference to only the token object instead of the whole manager.

So, if I had something to say (which I have not, I know that), I would argue
for keeping release, implementing the Token/Request/Prototype design, and
for "Token" as the name of the new interface/object.  If that would not work
I would go for second best IMO, which is lookup(String role, Object
hint)/hasComponent(String role, Object hint) release(Object).  

Marc

> -----Original Message-----
> From: Stefano Mazzocchi [mailto:stefano@apache.org]
> Sent: Thursday, June 06, 2002 3:18 PM
> To: cocoon-dev@xml.apache.org
> Cc: 'Avalon Developers List'
> Subject: Re: [Design] ContainerManager is under fire--let's find the
> best resolution
> 
> 
> Gosh, I forgot how strident can become talking about high level
> abstractions... remind me of the good old days when we were discussing
> what later became known as Avalon and Pier and I got such a huge fight
> for a simple method.
> 
> ihihih, discussing such high-level abstractions can get really nasty
> ego-wise :)
> 
> Berin Loritsch wrote:
> > 
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > >
> > > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> blah blah blah
> 
> Let's clear up the table.
> 
> Berin is proposing a better CM and I like it more than what Avalon 4
> has. First of all, it removes that stupid "pass non-exceptional info
> with exceptions" design pattern.
> 
> Ah, BTW, there are *tons* of places where this happens in Avalon,
> please, make sure the above anti-pattern is removed from Avalon 5.
> 
> Then it removes the need for that hacky ComponentSelector, unifying
> approaches.
> 
> Anyway, despite a few issues I'm having (I don't see why we should
> return an Object instead of a Component. That's a component selector,
> not an object selector. There is the Class object for that!) 
> I see it as
> a step forward.
> 
> 
> The problem is garbage collection of components.
> 
>                                    - o -
> 
> WARNING: radical changes ahead, this is not for the faint-hearted! YOU
> HAVE BEEN WARNED!
> 
> Let's make one step back: what is an avalon component?
> 
> I'm pretty sure that everybody has a different idea on what 
> this really
> is, but here is my personal one: 
> 
>   an avalon components is the implementation of a functional 
> description
> 
> [so far, is nothing different from a normal class implementing an
> interface]
> 
>   and exposes behavioral modifiers
> 
> This is the difference between an Avalon component and a java class
> implementing an interface: the way the class is created.
> 
> [the other differences are functional, not conceptual]
> 
> In Java, the only way to modify how a class is constructed is 
> to call a
> different constructor method. Unfortunately, java doesn't define
> "construction prototypes" but only 'functional prototypes' (with
> interfaces).
> 
> This left the original Avalon designers with one radical solution:
> deprecate the use of constructors and create a totally different
> construction lifecycle.
> 
> First, we thought about creating a ComponentFactory, something like
> 
>  public class ComponentFactory {
>     Component createComponent(String componentName);
>  }
> 
> but soon we realized that the ability to separate the concern of
> creation from that of use, we could simply create pools of pre-created
> objects. So, in that case, createComponent() was a bad name 
> and Factory
> too limiting.
> 
> This lead to the concept of a ComponentManager, the 'director' of the
> 'play', where each actor asks the director to indicate what person
> performs a particular role in the play, in order to be able to
> communicate with it.
> 
> The CM is also able to 'instruct' a new actor to perform a particular
> role. So, from a design pattern point of view, "Manager extends
> Factory".
> 
> We didn't think about role collisions: blinded by the 'play metaphor',
> we thought that there was no need, on stage, for two actors acting the
> same role with dressed up in different colors. On later 
> thought, this is
> not true: it is the rule that important carachters in the play has a
> 'backup'. In that case, an actor might ask not only the role 
> played, but
> also the 'hint' (official/backup) to obtain the reference to the other
> actor.
> 
> So, it makes perfect sense to merge the two aspects into a single CM.
> 
> So far so good.
> 
>                                    - o -
> 
> Two steps back, now.
> 
> Before the introduction of automatic garbage collection, everybody
> allocated memory, used it and freed it when it was not needed. Failing
> to do the last part provided those infamous 'memory leaks' that almost
> all programs in the world suffer.
> 
> In more abstracted languages where you don't have direct access to the
> memory, you don't allocate it directly, but you create an functional
> entity (object, for example), you use it, then you dispose it.
> 
> This is less error prone because it's more abstract, but 
> still requires
> people to know what they are doing and don't forget to dispose those
> objects which aren't needed.
> 
> Enter garbage collection: at the price of a system overhead, the
> programmer is released from the responsibility to provide explicit
> disposal for the objects he creates.
> 
> You know what? I'm starting to think that the java GC is a gigantic
> mistake. Why? simple, it's useless.
> 
> A GC continue to skeep thru your object space to look for 'detached'
> objects. That's a great implementation, but what if I forgot 
> to 'detach'
> those objects?
> 
> If GC was that effective, why Java programs leak memory anyway?
> 
> Some people believe that Java is inherently safer than C 
> because it has
> garbage collection that prevents people from shooting 
> themselves in the
> foot with direct pointers to memory.
> 
> WRONG!
> 
> It's the absence of pointers that make Java safer, not the 
> capability of
> the VM to clean up your mess for you. It can't! It can't be 
> smarter than
> you no matter how hard you try! 
> 
> If I was to rewrite java from scratch I would simply make that stupid
> and utterly useless
> 
>  Object.finalize()
> 
> method active and native instead of passive and empty! 
> 
> So, instead of doing
> 
>  HashMap map = new HashMap();
>  map.add("a","1");
>  map.add("b","2");
> 
>  ...
> 
>  map = null // let's make it ready for GC
> 
> you call your stinking
> 
>  map.finalize();
> 
> [much better names would be destroy(), dispose(), cleanup()]
> 
> that invalidates it and turns 'map' into a null and recursively
> invalidates all those objects that are not bound to any other object
> (this can be done asynchronously, but it's a VM implementation detail)
> 
>                                    - o -
> 
> Berin points out that people might forget to dispose thier components,
> thus producing leaks. If made automatic, component GC could eliminate
> this problem entirely and make it easier to use Avalon.
> 
> I agree on the intention but I question the effectiveness of the
> approach: Java has shown that GC doesn't eliminate memory 
> leaks because
> the program has no way to interact with the garbage 
> generation strategy
> of the JVM.
> 
> This was somewhat changed with WeakReferences: the GC treats 
> objects and
> weakobjects differently. Unfortunately, these are hardcoded GC
> strategies and there is no way to create ThreadGroupObjects or other
> similar GC strategy aspects.
> 
> It's evident: the java architects didn't bother much at making object
> construction strategies more aspect oriented, and they did 
> the same with
> object destruction.
> 
> So, from an elegance point of view, it makes perfect sense, 
> for Avalon,
> to provide aspect-oriented construction strategies *and* 
> aspect-oriented
> destruction strategies.
> 
> Just like it's the component manager's concern to construct your
> component the way the component was instructed to (depending on the
> interfaces it implements), similarely, it should be the component
> manager's concern (or some proxy slave, that's an 
> implementation detail)
> to dispose the component, depending on the disposing strategy that the
> component implements.
> 
>                                     - o -
> 
> The only concern I have is the fact that the dispose() method 
> for the CM
> might still be required for all those cases where the 
> strategy might not
> apply correctly, or for those cases where a strategy would need native
> access to the JVM to fully obtain enough information to perform.
> 
> I think that even if we come up with a transparent component 
> disposable
> strategy framework, the dispose() method in the CM woudn't hurt and
> would keep everybody happy.
> 
> -- 
> Stefano Mazzocchi      One must still have chaos in oneself to be
>                           able to give birth to a dancing star.
> <st...@apache.org>                             Friedrich Nietzsche
> --------------------------------------------------------------------
> 
> 
> 
> --
> To unsubscribe, e-mail:   
<ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>

---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Marc Schier [mailto:MSchier@infogation.com]

<snip/>

> IMO, the best design comes from Berin's initial proposal, which is the
> Token/Request/Prototype implementation including a release on the
token.
> This is the cleanest way to work with the CM.  The code inside the
component
> will be much nicer and cleaner and it would also allow the component
to
> obtain a reference to only the token object instead of the whole
manager.
> 
> So, if I had something to say (which I have not, I know that), I would
argue
> for keeping release, implementing the Token/Request/Prototype design,
and
> for "Token" as the name of the new interface/object.  If that would
not work

This one

> I would go for second best IMO, which is lookup(String role, Object
> hint)/hasComponent(String role, Object hint) release(Object).

is funny: it resembles interface I have in the framework forked from
Avalon 3.0 alpha 3 (did that for a client, almost 2 years ago...)

:)

Vadim

> Marc



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>