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

WebView leaks memory when containing object acts as javascript callback handler

    XMLWordPrintable

Details

    • 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

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

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported: