JDK-8144502 : WebView never releases resources
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 9
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-11-29
  • Updated: 2016-06-20
  • Resolved: 2016-06-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Blocks :  
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.9.0-ea"
Java(TM) SE Runtime Environment (build 1.9.0-ea-b93)
Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b93)


ADDITIONAL OS VERSION INFORMATION :
ver 6.1 - Windows 7 Professional, Version 6.1 (Build 7601, Service Pack 1)


A DESCRIPTION OF THE PROBLEM :
WebView never releases resources until the JVM is closed. This simple example is used to open and close an example of WebView to show that resources are never recovered by the GC.
The problem occurs on 1.8.0_72 and 1.9.0 current build 93.
When the program initially runs on Windows 7 the JVM uses 5-60 Mb of memory.
When the Open button is clicked WebView increases that to 180Mb.
When the Close button is clicked everything is done to de-activate/dereference WebView but memory is never released.
Repeatedly clicking on Open, then Close will gradually increase the memory used to 280Mb.
If the url is changed (not shown in this example) the problem is worse.
The only way to recover the resources is to stop the JVM.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the example below, I am also sending the java file as an attachment.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When one clicks on the Close button WebView resources should be recovered by the GC

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package memorytests;
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class MemoryTests extends Application {
    Browser browser= null;
    
    @Override
    public void start(Stage stage) {
        Button button= new Button("Open");
        VBox vbox= new VBox();
        vbox.getChildren().add(button);
        Scene scene= new Scene(vbox,800,600);
        
        button.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    if(browser==null) {
                        browser= new Browser("http:\\www.yahoo.com");
                        vbox.getChildren().add(browser);
                        button.setText("Close");
                    }
                    else {
                        vbox.getChildren().remove(browser);
                        browser.close();
                        browser= null;
                        button.setText("Open");
                    }
                }
            });
        
        stage.setTitle("WebView Memory Problem");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class Browser extends VBox {
    VBox thisTab;
    WebView webView = new WebView();
    Browser(String urlString) {
        thisTab= this;
        webView.getEngine().load(urlString);
        this.getChildren().add(webView);
    }
    
    void close() { // do everything we can to help release resources
        thisTab.getChildren().clear();
        thisTab= null;
        webView.getEngine().setJavaScriptEnabled(false);
        Worker worker= webView.getEngine().getLoadWorker();
        if(worker.isRunning()) worker.cancel();
        webView.getEngine().loadContent(null);
        webView= null;
    }
}

---------- END SOURCE ----------