Subject Re: [Firebird-Java] Re: Should (Could) FBStatements be held in WeakHashMap
Author Mark O'Donohue
Hi Robert

Robert DiFalco wrote:

> You bring up some great points and the timings don't look as bad as I
> would expect, but possibly with a system loaded down with a lot of other
> objects you might find things a little different.
>

True, but we need to start somewhere :-).


> So you bring up a pretty good point. If I use the API correctly and
> don't make the WeakHashMap work, I should block to discard weak
> references.

> I feel a bit better after our examining this. Thanks for indulging me.
>

No worries, it certainly was worth having a closer look at it, there is
a bit more of the techo answer stuff below.

Cheers

Mark



>
> In your test, you would have never seen blocking from this because you
> released the weak references.


Yep, that's true. I'd added the close() to my junit test to test normal
operation. The original junit test case, testing for the error
condition looked like this:


maxStmt = 80000;

for (int i = 0; i < maxStmt; i++) {
Statement stmt = con.createStatement();
}

When close() was skipped, and in the tight loop, the WeakHashMap
regularly had 4000 entries it it. If the createStatment() really did
block until all weak references had been removed, I would expect the
internal WeakHashMap to only ever have one entry in it.

In fact, in building the junit test case, I found that to completely
empty the WeakHashMap of all weak references, even calling System.gc()
wasn't enough. I had to call Thread.sleep() for a while as well in the
main thread. I assume this is just a byproduct of the JVM loadbalancing.

>
> I could be wrong, I basically just looked at the code for WeakHashMap
> and almost every call uses "getTable" which looks something like this:
..snip...
> And "expungeStaleEntries" looks like this:
..snip...
> while ( (r = queue.poll()) != null) {
>
>
> So, to me it looks like you would block to clean up references (if
> there were any) on each call. For example, both "get()" and "put()"
> call "getTable()".

My guess on what is happening internally, is that although poll() is
called each time, perhaps the gc hasn't had time to identify the objects
as being weakly reachable as yet.

Cheers

Mark