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

WebView leaks memory when containing object acts as javascript callback handler

    Details

    • Subcomponent:
      web

      Backports

        Description

        I use a WebView that is contained in an extension of a Pane class (lets call it the view) and then use the view as the javascript callback handler. If I now close the application window without quiting (no implicit exit) the view and all of its memory is not reclaimed.

        Here is some example code with a large long[] array that takes about 80MB of RAM so the leak is easy to spot in jvisualvm:



        package bugreports;

        import javafx.application.Application;
        import javafx.application.Platform;
        import javafx.concurrent.Worker;
        import javafx.scene.Scene;
        import javafx.scene.layout.BorderPane;
        import javafx.scene.web.WebView;
        import javafx.stage.Stage;
        import netscape.javascript.JSObject;

        public class WebEngineNotReleasingMemory extends Application
        {
        static final String html = "<!DOCTYPE html>" +
        "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-16\">" +
        "<html>" +
        "<button type=\"button\" onClick=\"javaCallback.sayWorld()\">Hello</button>" +
        "</html>";

        public static final class CallbackView extends BorderPane
        {
        private final long[] memoryWaster = new long[10000000];


        private final WebView view = new WebView();

        public CallbackView()
        {
        view.getEngine().getLoadWorker().stateProperty().addListener((ov, o, n) -> {
        if (n == Worker.State.SUCCEEDED)
        {
        final JSObject window = (JSObject) view.getEngine().executeScript("window");
        assert window != null;
        window.setMember("javaCallback", this);
        }
        });

        view.getEngine().loadContent(html);
        setCenter(view);
        }

        // called from JavaScript
        public void sayWorld()
        {
        System.out.println("World!");
        }
        }

        @Override
        public void start(final Stage primaryStage) throws Exception
        {
        Platform.setImplicitExit(false);

        final CallbackView pane = new CallbackView();
        primaryStage.setScene(new Scene(pane));
        primaryStage.show();
        }

        }



        How to reproduce:
        1) Run the application
        2) Close the window
        3) Connect with jvisualvm to the application and force garbage collection, memory is not being reclaimed

          Attachments

          1. MemoryLeak.png
            MemoryLeak.png
            44 kB
          2. MemoryLeak_MAX.png
            MemoryLeak_MAX.png
            48 kB
          3. Monitor-Heap.png
            Monitor-Heap.png
            56 kB
          4. Monitor-Heap-1.png
            Monitor-Heap-1.png
            53 kB

            Issue Links

              Activity

                People

                • Assignee:
                  mbilla Murali Billa
                  Reporter:
                  cmuthingjfx Clemens Muthing (Inactive)
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  9 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:
                    Imported: