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

Out of memory exception due to repeated style class changes

    Details

    • Subcomponent:
    • CPU:
      x86
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_122-ea"
      Java(TM) SE Runtime Environment (build 1.8.0_122-ea-b04)
      Java HotSpot(TM) 64-Bit Server VM (build 25.122-b04, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      OS X 10.10.5 (but not relevant for the bug)

      A DESCRIPTION OF THE PROBLEM :
      I am just reviewing a multi-media application written in JavaFX which runs out of memory after some time of working with it. The analysis shows that this is due to the fact that this applications constantly changes images in an ImageView via changing the CSS class of this view. The single CSS file contains a lot of definitions like this:

      .image-view-HGWechsel-1 {
      -fx-image:url(pics/lesebereich_bg/01_Hintergrund_Lesebereich_1920x1080.jpg) ;
      }

      .image-view-HGWechsel-2 {
      -fx-image:url(pics/lesebereich_bg/02_Hintergrund_Lesebereich_1920x1080.jpg) ;
      }

      Whenever the view is supposed to change, the old style class is removed and a new one is set. The problem now is that JavaFX caches all these images although only one of them is used at a time and never releases this cache and so finally runs out of memory.

      Fix:

      In com/sun/javafx/css/StyleManager.java replace the line

          private final Map<String,Image> imageCache = new HashMap<String,Image>();

      with

          private final static class ImageCache {
           private SoftReference<Map<String,Image>> softImageCache = new SoftReference<Map<String,Image>>(new HashMap<String,Image>());

           Map<String,Image> getCache() {
           Map<String,Image> tmpImageCache = softImageCache.get();
           if (tmpImageCache == null) {
           tmpImageCache = new HashMap<String,Image>();
           softImageCache = new SoftReference<>(tmpImageCache);
           }
           return tmpImageCache;
           }
          
          }

          private final ImageCache imageCache = new ImageCache();

      and then replace the few references to "imageCache" with "imageCache.getCache()". This will effectively prevent the application from crashing because all cached but currently not used images can be released now in case memory gets low.

      Additional note: There is a second instance of an imageCache in the inner class StylesheetContainer which never seems to be used. If this is true you might want to remove this.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See description.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Released cached images when application is running out of memory.
      ACTUAL -
      Does not release cached images when application is running out of memory and just preferes to die.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      CUSTOMER SUBMITTED WORKAROUND :
      Apply the patch shown in the description.

        Attachments

          Activity

            People

            • Assignee:
              arapte Ambarish Rapte
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: