I tried to make the UI by using webview in JavaFX, but there is one problem, when a large image is opened using popup, memory usage is very large, and when the popup is closed, the memory usage does not go down, I see the memory usage via the Task Manager in Windows ,

when the image with a size of approximately 8MB opened using webview, memory reached 300MB in use, I do not understand why it is so large,

I've tried

stage.setOnCloseRequest(new EventHandler<WindowEvent>() {

        @Override
        public void handle(WindowEvent event) { 
            webengine.load(null);   

        }
    });

but still, do not make the memory freed

有帮助吗?

解决方案

Possibly, you are seeing an instance of RT-33729 WebView leaks WCImgDecoderImpl instances, currently targeted to be fixed for Java 8u20. In RT-33729, a developer (Leonid Popov) writes:

Webkit has a cache of resources used for web pages, including images. It continues to keep unused ("dead") resources even after they are not referenced anymore just in case the user presses "Back" to avoid loading of already loaded resources, while they don't retain too much heap space. See details in comments in the Webkit source code:

http://trac.webkit.org/browser/trunk/Source/WebCore/loader/cache/MemoryCache.h

Instances of WCImgDecoderImpl are referenced through JNI by ImageSource's referenced by BitmapImage's referenced by CachedImage's stored in MemoryCache. I tested it with modifying the cache so that it completely swept out its cached resources, and observed that all WCImgDecoderImpl's have gone. While an instance of WCImgDecoderImpl can be accessed from WebKit native code, it's not useless. The point is that it is WebKit who rules the lifecycle of WCImgDecoderImpl through JNI. Investigation of how this cache could be flushed forcibly on WebView removal, is still going on.

Talking about the test app from the description. When you remove a WebView from the scene, it doesn't get deleted immediately (and so it doesn't release any resources). Instead, it has a disposer registered at the disposer thread (similar to the one used by AWT) that should call it back in certain time and cause native resources being used by WebEngine to release.

Also, I'd recommend to navigate to "about:blank" before removing WebView; it would make it to release some resources immediately.

But, maybe you are seeing something else entirely, I couldn't tell you definitively, such as whatever causes RT-35262 JVM crash due to memory leak in WebView/Webkit, also due to be resolved for Java 8u20 or RT-34630 WebView memory leak when JavaScript callbacks are assigned, due to be resolved for Java 9.

其他提示

My Code (works for me), inspired by jewelsea's answer.

// Delete cache for navigate back
webEngine.load("about:blank");
// Delete cookies 
java.net.CookieHandler.setDefault(new java.net.CookieManager());

I have searched the internet extensively and found all kind of solutions, unfortunately none of them worked form me. It looks like, no matter what is being done, the scene is chached by the JFXPanel. What worked for me was the following;

Scene scene = getScene();
jfxPanel.removeAll();
jfxPanel.setScene(scene);
WebView webView = (WebView) scene.getRoot();
webView.getWebEngine().load(url);

The getScene() re-uses the formerly created Scene (with its Webview and WebEngine), when creating a new Scene the JFXPanel gets invisible. So the solution lies in removing and re-setting the existing Scene and then loading the url.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top