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

exception during ClassValue.remove permanently breaks the ClassValue

    Details

    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 13
    • Fix Version/s: tbd
    • Component/s: core-libs
    • Labels:
      None

      Description

      If ClassValueMap.removeEntry gets something like OutOfMemoryError here:

                      // In an initialized state. Bump forward, and de-initialize.
                      classValue.bumpVersion();

      then the ClassValue is permanently broken. Future calls to remove() will do nothing, and computeValue will never be called again. Instead, the value will be supplied from the cache.

      % cat CV.java

      import java.util.ArrayList;
      import java.util.List;

      public class CV {

          static int version = 0;
          static final ClassValue<String> resolvedJavaType = new ClassValue<>() {
            @Override
            protected String computeValue(Class<?> type) {
              return type.getName() + (++version);
            }
          };

          static void eatMemory(List<Object> list) {
              int size = 1000000;
              while (true) {
                  try {
                      list.add(new Object[size]);
                  } catch (OutOfMemoryError oom) {
                      size /= 2;
                      if (size == 0) {
                          return;
                      }
                  }
              }
          }

          public static void main(String[] args) {
      var v1 = resolvedJavaType.get(CV.class);
      List<Object> storage = new ArrayList<Object>();
      boolean done = false;
      while (!done) {
      eatMemory(storage);
      try {
      resolvedJavaType.remove(CV.class);
      } catch (Throwable t) {
      done = true;
      storage = null;
      }
      }
      resolvedJavaType.remove(CV.class);
      var v2 = resolvedJavaType.get(CV.class);
      System.err.println("v1 " + v1);
      System.err.println("v2 " + v2);
      System.err.println("max version " + version);
      if (version != 2 || v1 == v2) {
      throw new RuntimeException("Failed");
      }
          }
      }

      % javac CV.java
      % java -Xmx64m CV
      v1 CV1
      v2 CV1
      max version 1
      Exception in thread "main" java.lang.RuntimeException: Failed
      at CV.main(CV.java:47)

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                jrose John Rose
                Reporter:
                dlong Dean Long
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated: