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

Memory leak caused by Parent#removed not being freed

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 8u60
    • Fix Version/s: 9
    • Component/s: javafx
    • Labels:
    • Subcomponent:
    • CPU:
      x86_64
    • OS:
      windows_7

      Backports

        Description

        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.

          Attachments

            Issue Links

              Activity

                People

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

                  Dates

                  Created:
                  Updated:
                  Resolved: