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

WebView leaks memory when containing object acts as javascript callback handler

XMLWordPrintable

    • web

        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

          1. MemoryLeak.png
            44 kB
            Murali Billa
          2. MemoryLeak_MAX.png
            48 kB
            Murali Billa
          3. Monitor-Heap.png
            56 kB
            Murali Billa
          4. Monitor-Heap-1.png
            53 kB
            Murali Billa
          There are no Sub-Tasks for this issue.

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

                Created:
                Updated:
                Resolved:
                Imported: