Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8024421

(ref) GC should clear PhantomReference

    Details

    • Type: Enhancement
    • Status: Closed
    • Priority: P3
    • Resolution: Won't Fix
    • Affects Version/s: 7
    • Fix Version/s: None
    • Component/s: hotspot
    • Labels:
      None
    • Subcomponent:
      gc

      Description

      A DESCRIPTION OF THE REQUEST :
      Phantom references should be cleared by the garbage collector as they are enqueued.

      JUSTIFICATION :
      Keeping phantom reachable objects in heap has some drawbacks:
      1. At least 2 GC are required in order to reclaim them, even in case when application code pulls references from reference queue and clears them promptly.
      2. GC pauses are increased since phantom reachable objects are still to be marked.

      On the other hand, benefits are not obvious. Its referent cannot be used since it's not accessible.


      ACTUAL -
      attached test fails with OOM:
      Exception in thread " main " java.lang.OutOfMemoryError: Java heap space
      at test.RefHugeTest.newHugeObject(RefHugeTest.java:34)
      at test.RefHugeTest.main(RefHugeTest.java:13)


      ---------- BEGIN SOURCE ----------
      package test;

      import java.lang.ref.PhantomReference;
      import java.lang.ref.Reference;
      import java.lang.ref.ReferenceQueue;
      import java.lang.ref.SoftReference;
      import java.lang.ref.WeakReference;

      public class RefHugeTest {
          public static void main(String[] args) throws IllegalArgumentException, InterruptedException {
              ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
              Reference<Object> reference = newReference(newHugeObject(), queue);
              Object huge = newHugeObject();
              drainReferences(queue);
              System.out.println( " ok " );
          }

          private static void drainReferences(ReferenceQueue<Object> queue) {
              Reference<?> ref;
              while ((ref = queue.poll()) != null) {
                  ref.clear();
              }
          }

          private static <T> Reference<T> newReference(T referent, ReferenceQueue<? super T> queue) {
              Reference<T> reference = new PhantomReference<T>(referent, queue);
      // Reference<T> reference = new SoftReference<T>(referent, queue);
      // Reference<T> reference = new WeakReference<T>(referent, queue);
              return reference;
          }

          private static Object newHugeObject() {
              int size = (int) (Runtime.getRuntime().maxMemory() * 2 / 3);
              return new byte[size];
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      use weak references and avoid finalizers.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                mcastegr Mattis Castegren (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: