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

(prefs) AbstractPreferences: memory waste by empty listener arrays

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 8u51
    • core-libs

      A DESCRIPTION OF THE REQUEST :
      The fields nodeListeners and prefListeners are initialized with new empty arrays. It is rather likely that they will stay empty, thus for each preference instance such empty arrays are created.

      I propose to create a constant empty array that is used as default value, thus there is just a single array.

      Proposed change:
          private static final PreferenceChangeListener[] NO_PREF_LISTENERS = new PreferenceChangeListener[0];
          private PreferenceChangeListener[] prefListeners = NO_PREF_LISTENERS;
              


      JUSTIFICATION :
      I am inspecting potential for memory optimization for an Enterprise software and found in YourKit that the most zero-length array were allocated in AbstractPreferences. The program has 3500 preferences instances, which leads to 100kB memory waste.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      All AbstractPreference instances share a single array of listeners until addNode/PreferenceChangeListener was called.
      ACTUAL -
      see Description

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

      import java.lang.reflect.Field;
      import java.util.prefs.AbstractPreferences;
      import java.util.prefs.BackingStoreException;

      import org.junit.Assert;
      import org.junit.Test;

      public class PrefTest {
      static class MyPrefs extends AbstractPreferences {

      protected MyPrefs() {
      super(null, "");
      }

      protected void putSpi(String key, String value) {}
      protected String getSpi(String key) { return null; }
      protected void removeSpi(String key) { }
      protected void removeNodeSpi() throws BackingStoreException {}
      protected String[] keysSpi() throws BackingStoreException { return null; }
      protected String[] childrenNamesSpi() throws BackingStoreException { return null;}
      protected AbstractPreferences childSpi(String name) { return null; }
      protected void syncSpi() throws BackingStoreException { }
      protected void flushSpi() throws BackingStoreException {}
      }
      @Test
      public void test_prefListener () throws Exception {
      MyPrefs p1 = new MyPrefs();
      MyPrefs p2 = new MyPrefs();
      Field prefListenersField = AbstractPreferences.class.getDeclaredField("prefListeners");
      prefListenersField.setAccessible(true);
      Assert.assertSame (prefListenersField.get(p1), prefListenersField.get(p2));
      }
      }

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

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: