RFR: 8071507: (ref) Clear phantom reference as soft and weak references do

Per Liden per.liden at oracle.com
Fri Dec 4 07:16:36 UTC 2015


Hi Kim,

On 2015-12-02 19:37, Kim Barrett wrote:
> Please review this change to PhantomReference processing, changing the
> GC-based notification to automatically clear the referent.
>
> This change provides performance benefits by eliminating the work
> involved in keeping the otherwise inaccessible referent objects alive,
> as required by the existing specification. This not only immediately
> removes some work, but may enable further performance improvements.
> It also allows the referent objects to be immediately reclaimed in
> the GC cycle in which they were determined to be inaccessible, rather
> than lingering as a form of floating garbage until the application
> deals with the notified reference.
>
> This change results in a behavioral change to application code, as
> demonstrated by the associated test.  Under the old specification, a
> reference R with referent X may be kept alive because it is referenced
> by an otherwise inaccessible referent Y of phantom reference P.  This
> will result in X being treated as strongly referenced and prevent R
> from being notified, even if R is a phantom reference and X has become
> inaccessible to the application.  With this change, Y is reclaimed
> when it becomes inaccessible and P is notified, and no longer prevents
> X from itself becoming a candidate for reclaimation once it is no
> longer accessible to the application.  While this is a change in
> behavior, it seems unlikely to affect applications negatively.
>
> CR:
> https://bugs.openjdk.java.net/browse/JDK-8071507
>
> Webrevs:
> http://cr.openjdk.java.net/~kbarrett/8071507/jdk.05/

test/java/lang/ref/PhantomReferentClearing.java:

   85         // Delete root -> O1, collect, verify P1 notified, P2 not 
notified.
   86         O1 = null;
   87         System.gc();
   88         if (Q1.remove(ENQUEUE_TIMEOUT) == null) {
   89             throw new RuntimeException("P1 not notified by O1 
deletion");
   90         } else if (Q2.remove(ENQUEUE_TIMEOUT) != null) {
   91             throw new RuntimeException("P2 notified by O1 deletion.");
   92         }
   93
   94         // Delete root -> O2, collect. P2 should be notified.
   95         O2 = null;
   96         System.gc();
   97         if (Q2.remove(ENQUEUE_TIMEOUT) == null) {
   98             throw new RuntimeException("P2 not notified by O2 
deletion");
   99         }

The calls to System.gc() isn't guaranteed to do what the test expects 
here. As you know, System.gc(), might not actually do anything, 
depending on which collector is used and the current circumstances (GC 
locker held, a concurrent GC is already in process, etc). To make the 
test robust I'd suggest you call System.gc() and check the queue in a 
loop, and fail after some reasonable amount of time/iterations.

cheers,
/Per

> http://cr.openjdk.java.net/~kbarrett/8071507/hotspot.05/
>
> Testing:
> jprt, aurora ad hoc (defaults, GC/Runtime nightly, JCK)
>



More information about the core-libs-dev mailing list