Relates :
|
|
Relates :
|
|
Relates :
|
Consider the following test program: import java.lang.ref.*; import java.util.*; public class RefCompliance { RefCompliance () { } public static void test() { int[] o1 = new int[10]; WeakReference w1 = new WeakReference(o1); SoftReference s1 = new SoftReference(w1); int[] o2 = new int[10]; WeakReference w2 = new WeakReference(o2); SoftReference s2 = new SoftReference(w2); int[] o3 = new int[10]; WeakReference w3 = new WeakReference(o3); o1 = null; o2 = null; o3 = null; w2 = null; // Scrub stack because of conservative collector int[] dummy1 = new int[10]; int[] dummy2 = new int[10]; System.gc(); int res1; w2 = (WeakReference)s2.get(); if (w1 == s1.get()) { res1 = 0; if (w1.get() == null) { res1 += 100; } if (w2.get() == null) { res1 += 10; } if (w3.get() == null) { res1 += 1; } } else { res1 = -1; } if (res1 == 101) { System.err.println("JDK1.2"); } else if (res1 == 111) { System.err.println("weakest link on strongest chain"); } else if (res1 == 001) { System.err.println("API spec"); } else { System.err.println("unknown: result " + res1); } } public static void main(String[] args) { test(); test(); test(); test(); test(); } } When run with JDK1.2 it outputs "JDK1.2". According to my understanding of the API spec, it should instead output "API spec". Because the JDK uses a conservative collector, it is also possible that no refs will be cleared and the test will output "API spec" for JDK1.2. This is because a stale reference to the referent might be found on the C or Java stack, preventing the ref from being cleared. For this reason the test is run multiple times. My tests show the full output as: API spec JDK1.2 JDK1.2 JDK1.2 JDK1.2 for JDK1.2, and weakest link on strongest chain weakest link on strongest chain weakest link on strongest chain weakest link on strongest chain weakest link on strongest chain for a modified VM that attempts to implement the "intuitive" behavior. My guess is that the Solaris "Exact" VM would print "JDK1.2" each time. dean.long@Eng 1999-02-24
|