On 03/07/2013 11:09 PM, Thomas Neidhart wrote:
> Hi,
> 
> I have installed the following JDK on my machine:
> 
> java version "1.6.0"
> Java(TM) SE Runtime Environment (build pxi3260sr12-20121025_01(SR12))
> IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux x86-32
> jvmxi3260sr12-20121024_126067 (JIT enabled, AOT enabled)
> J9VM - 20121024_126067
> JIT  - r9_20120914_26057
> GC   - 20120928_AA)
> JCL  - 20121014_01
> 
> When I try to run the following test from the IBM developerworks wrt
> WeakReferences and ReferenceQueue, the reference is never put on the
> reference queue (the problem that I also had in the WeakHashtable testcase):
> 
> url: http://www.ibm.com/developerworks/library/j-refs/
> 
> output:
> 
> Example of incorrectly holding a strong reference
> object is MyObject@3b203b2
> The weak reference is java.lang.ref.WeakReference@46d046d
> Polling the reference queue returns null
> Getting the referent from the weak reference returns MyObject@3b203b2
> Calling GC
> Polling the reference queue returns null
> Getting the referent from the weak reference returns null
> 
> Example of correctly releasing a strong reference
> object is MyObject@2bd62bd6
> The weak reference is java.lang.ref.WeakReference@37c637c6
> Polling the reference queue returns null
> Getting the referent from the weak reference returns MyObject@2bd62bd6
> Set the obj reference to null and call GC
> Polling the reference queue returns null
> Getting the referent from the weak reference returns null
> In finalize method for this object: MyObject@3b203b2
> In finalize method for this object: MyObject@2bd62bd6
> 
> 
> Polling the reference queue always returns null, even when the
> WeakReference has lost its referent.
> 
> Can somebody confirm this?

Obviously the IBM JDK does put released references much later on the
reference queue than the Sun/Oracle/OpenJDK one.

In the testcase from above, it takes some time (replace the queue.poll
with a while and after ~ 10/20 iterations it is on the queue).

I still do not know why in the WeakHashtable test case it is not put on
the queue even after several minutes.

Anyway, the logic in WeakHashtable is flawed, as it relies on the queue
to purge elements from the table. When considering for example the
elements method:

    public Enumeration elements() {
        purge();
        return super.elements();
    }

This purges any elements whose key is put into the queue and then
delegates to super.elements. When a key that has already been gc'ed
(Reference.getKey == null), but not yet been put on the queue, the
corresponding WeakKey is still contained in the map, and thus,
super.elements() will return this element.

Other methods like keySet also check if the referent of the
WeakReference is null and omit such entries from the reply, thus leading
to different results, leading to different results than e.g. size().

In logging, there are 5 methods from WeakHashtable used:

 * get
 * put
 * remove
 * elements
 * clear

The only problematic one being elements, and it is used to release all
registered factories, so this should be safe imho.

We could change the purge method to not rely on the queue, but always
iterate over the entrySet and remove the entries whose referent key is
null and update the testcase to ignore the queue?

Thomas

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to