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_MAX.png
            MemoryLeak_MAX.png
            48 kB
          2. MemoryLeak.png
            MemoryLeak.png
            44 kB
          3. Monitor-Heap.png
            Monitor-Heap.png
            56 kB
          4. Monitor-Heap-1.png
            Monitor-Heap-1.png
            53 kB

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

                Created:
                Updated:
                Resolved:
                Imported: