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

Memory leak caused by Parent#removed not being freed

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 9
    • 8u60
    • javafx
    • x86_64
    • windows_7

        FULL PRODUCT VERSION :
        java version "1.8.0_60"
        Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
        Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.1.7601]

        A DESCRIPTION OF THE PROBLEM :
        When child nodes are removed from a JavaFX parent, references to these nodes are held in a list ('removed'). This list is usually cleared when the scene graph is updated via Parent#impl_updatePeer.

        If, however, you remove the parent from the scene graph (e.g. for emulating a card layout) the references will not be released. The 'removed' list is populated, but never cleared.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        The sample program attached below illustrates the issue. Run the application and attach to the running VM using jProfiler or a similar tool to verify that the allocated memory is indeed not freed.




        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Even though TestApp holds a reference to 'someParent', no reference to the BigComponent instance is being held in user code. The allocated memory should therefore be freed.
        ACTUAL -
        The application maintains a heap usage of 1GB that cannot be collected. Using jProfiler you can confirm that the only path to the GC root for the BigComponent instance is indeed Parent#removed

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        public class TestApp extends Application {
            private BorderPane someParent = new BorderPane(new BigComponent());

            @Override
            public void start(Stage stage) throws Exception {
                final Scene scene = new Scene(someParent);

                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        scene.setRoot(new Label("Some other component"));
                        someParent.setCenter(null);
                    }
                });

                stage.setScene(scene);
                stage.show();
            }

            public static void main(String[] args) {
                Application.launch(TestApp.class, args);
            }

            private class BigComponent extends Pane {
                private double[] memoryHog = new double[1024*1024*128];
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        None. The implementation in Parent would probably benefit from using WeakReferences for the 'removed' list.

              ckyang Chien Yang (Inactive)
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: