> From: Niclas Hedhman [mailto:[EMAIL PROTECTED] 
>
> Leo & Leo,
> 
> you both represent the "theoretical committee", and I would 
> like to have your views on;
> 
> Spec for release() 
>   "Return the Object when you are finished with it. " 
> 
> The recent debate (close to flame war) over release() has 
> brought about a lot of arguments in favour and against the 
> method.
> 
> I would like to crystalize the issue to what I see as the 
> kernel of the apple;
> 
> Java don't have destructors.
> For a good reasons, of which I won't go into here (program 
> C++ for a couple of years to get the point).

My views on release(): I hate it. 

Unfortunately, it is the best solution I've been able to find 
so far. Rest assured that I'll campaign to have it removed / 
deprecated / ignored as soon as it is possible.
 
> Some objects NEEDS explicit destruction, e.g. FileInputStream.
> 
> Avalon re-introduces the destructor, in the form of 
> ServiceManager.release().
> 
> 
> Why is that such a good idea, when the destructor in Java is not?

OK, let's start with "why are destructors bad". Destructors, by
themselves, aren't bad. As a matter of fact, in C++ they are
very good, allowing you to release locks, close files and so
on. They also allow you to free memory - and *that* is what is
bad: Manual memory deallocation is bad. Because without a clear
understanding of who owns what block of memory, and who can and should
release it, you often end up blowing away the ground the code stands on
with a mistaken delete.

Since so many programmers spent so much time just managing something
as fundamental as memory, garbage collection was invented. Now,
all we have to ensure is to not keep references to unused memory -
and this is much easier than having to ensure that you can delete a
memory chunk.

So, to sum it up: Memory management is too hard. (Well, too hard in 
relation to the role it plays in most development - sometimes,
having and unpredictable GC is harder than to just do it yourself.)
So we came up with GC in order to manage memory for us.

Now, I'd like to emphasize one thing: We came up with GC in order to 
manage ***memory*** for us.

The Java GC is designed to manage memory. While memory is a resource,
all resources aren't equal: As we have seen with file handles, some
are scarce. Some have heavy initialization costs, like db connections.

Thus, when we try to use the Java GC, which is designed for memory 
management, to manage some other resource, we inevitably end up with
a suboptimal mapping.

Management of components if different from management of memory.
We have large initialization costs, for example. While un-freed
memory only does damage if you run low on memory, an un-released
component can do damage to your app's performance just by 
existing. While the GC can trigger on low memory, there is no
similar indicator to kick it into action saying that "you must
start disposing components *now*". Even if there were such an 
indicator, the GC doesn't trigger on it - remember, GC cares 
about memory management and nothing else.

So why is release() acceptable and manual dealloc bad? Because the 
latter is solved by GC, while the former is a different type of 
resource management. Components *have* memory, but *aren't* memory.
So you can't treat them as if they were.

Now, if we had some GC-for-components, then yes, release() would
be bad.


Irony: If we had C++ destructors, we could do away with release:

    void MyComponent::Service (ServiceManager const* manager)
    {
        Proxy<MyService*> service (manager, "role");
        // Do stuff with the proxy...
        service->DoStuff ();

        // No release needed, since the proxy goes out of scope.
    }

I believe C# has something similar, where an object that implements
IDisposable can be set to finalize upon exit from a block. I think
it is something like this:

    // MyClass implements IDisposable
    with (MyClass myInstance = new MyClass ()) do {
        myInstance.method1 ();
        // MyClass implements IDisposable, so
        // when we exit the with block, its dispose() method
        // is called.
    }

Correct me if I'm wrong, Hammett? On second thought make that: Please 
correct me since I'm wrong, Hammett.

I hope this explains my views on release().

/LS


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to