Java HtmlUnit内存泄漏

时间:2017-03-29 17:09:16

标签: java memory-leaks htmlunit

我收到了以下代码:

for (int i = 0; i < list.size(); i++) {
    navigate(list.get(i));
}

对于导航方法:

HtmlTextInput txtInput = page.getElementByName("input");
txtInput.setValueAttribute("random");


HtmlSubmitInput btnNext = page.getHtmlElementById("btn_next");
page = btnNext.click();


HtmlSubmitInput btnConfirm = page.getElementByName("submit");
page = btnConfirm.click();


System.out.println("before: " + webClient.getWebWindows().size());
page.cleanUp();
page.deregisterFramesIfNeeded(); 
System.out.println("after: " + webClient.getWebWindows().size());

return true;

HtmlPageWebClient已在全球范围内宣布。

为了正确看待,我填写表格,按OK,按确认,我被重定向到我的初始页面,所以我重复这个过程。问题是我的应用程序占用了所有内存。稍后会抛出一个堆异常。

如果算上网页,我看到这个数字在增长,而且从不减少。关于此内存泄漏的许多其他主题表明我必须调用.CloseAllWindows()方法,但此功能已被删除。

目前我正在使用HtmlUnit 2.25。

重定向时是否犯了错误,以便旧版Windows保留在后台?

更新版本:

创建新的WebClient方法:

private WebClient createNewWebClient(){
        WebClient webClient = new WebClient(BrowserVersion.FIREFOX_45);

        // no exceptions
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        // other settings 
        webClient.getOptions().setJavaScriptEnabled(true);
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setRedirectEnabled(true);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.getOptions().setTimeout(300000);

        // enable sessions
        webClient.getCookieManager().setCookiesEnabled(true);

        // Set session if any
        if (cookieManager == null){
            cookieManager = new CookieManager();
        } else {
            webClient.setCookieManager(cookieManager);
        }
        return webClient;
    }

Loop保持不变。导航方法:

     try (WebClient webClient = createNewWebClient()) {
                HtmlPage page = webClient.getPage("URL");
                HtmlTextInput txtInput = page.getElementByName("input");
                txtInput.setValueAttribute("random");


                HtmlSubmitInput btnNext = page.getHtmlElementById("btn_next");
                page = btnNext.click();


                HtmlSubmitInput btnConfirm = page.getElementByName("submit");
                page = btnConfirm.click();

             ...
       }

每次调用方法时内存仍在增加。

3 个答案:

答案 0 :(得分:1)

您需要致电webClient.close(),或者只需将其放入try-with-resources,例如:

try (WebClient webClient = new WebClient()) {
    String url = "http://localhost:8080";
    HtmlPage page = webClient.getPage(url);

    // do something
}

更新:

您可以存储CookieManager webClient.getCookieManager()并将其用于其他WebClient

答案 1 :(得分:0)

我也遇到同样的问题。经过数小时的调试和内存分析,我发现仅关闭Web客户端是不够的。您还需要清理加载的页面以释放所有嵌套的引用。

我将WebClient封装在另一个Closable类中。

因此,在您的情况下,这可以解决您的内存泄漏:

WebClient webclient = null;
HtmlPage page = hull;
try {
            webClient = createNewWebClient()
            page = webClient.getPage("URL");
            HtmlTextInput txtInput = page.getElementByName("input");
            txtInput.setValueAttribute("random");


            HtmlSubmitInput btnNext = page.getHtmlElementById("btn_next");
            page = btnNext.click();


            HtmlSubmitInput btnConfirm = page.getElementByName("submit");
            page = btnConfirm.click();

         ...
   } finally {
            page.cleanUp();
            webClient.close();
   }

答案 2 :(得分:0)

maimArt是正确的,在某些情况下,page.cleanUp();没有从webClient.close();中完全处理。此问题现已修复,将成为即将发布的2.44版本的一部分。

在这种情况下,如果您将问题报告给GitHub项目,那就太好了,否则我们没有机会解决。