有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JAVAlang.OutOfMemoryError:Htmlunit使用的Java堆空间

我试图通过使用htmlunit 2.16来废弃一些网站。网站内容有点重,有5000个左右的页面。在一些页面被废弃后,我遇到了Java堆空间问题。我已经分配了-Xms1500m和-Xmx3000m。但在运行30/45分钟后,它会将java抛出内存。以下是我的例子:

try (WebClient webClient = new WebClient(BrowserVersion.FIREFOX_38)) {
    webClient.getOptions().setJavaScriptEnabled(true);
    webClient.getOptions().setUseInsecureSSL(true);
    webClient.getCookieManager().setCookiesEnabled(true);
    webClient.getOptions().setThrowExceptionOnScriptError(false);
    webClient.getOptions().setPrintContentOnFailingStatusCode(false);
    webClient.setCssErrorHandler(new SilentCssErrorHandler());
    webClient.getOptions().setAjaxController(new NicelyResynchronizingAjaxController());

    // Get 1st page Data
    HtmlPage currentPage = webClient.getPage("www.example.com");

    for (int i = 0; i < 5000; i++) {
        try {
            HtmlElement next = (HtmlElement) currentPage
                .getByXPath("//span[contains(text(),'Next')]")
                .get(0);

            currentPage = next.click();
            webClient.waitForBackgroundJavascript(10000);
            System.out.println("Got data: " + currentPage.asXml());
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
    }
} catch (Exception e) {
    e.printStackTrace(System.err);
}

正如我们所看到的,我点击next按钮来获取内容。我也有。有人会面临类似的问题吗?它有内存泄漏吗


共 (2) 个答案

  1. # 1 楼答案

    也许问题是所有的页面仍然存储在历史记录中

    我通过以下方式禁用浏览历史记录:

        try {
            final History window = webClient.getWebWindows().get(0).getHistory();
            final Field f = window.getClass().getDeclaredField("ignoreNewPages_"); //NoSuchFieldException
            f.setAccessible(true);
            ((ThreadLocal<Boolean>) f.get(window)).set(Boolean.TRUE);
            LOGGER.debug("_dbff772d4d_ disabled history of Webclient");
        }
        catch (final Exception e) {
            LOGGER.warn("_66461112f7_ Can't disable history of Webclient");
        }
    

    我是从 how-to-limit-htmlunits-history-size


    这些配置与您的问题无关,但在我的项目中有用的地方:

        webClient.setJavaScriptTimeout(JAVASCRIPT_TIMOUT);
        webClient.getOptions().setTimeout(WEB_TIMEOUT);
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false); 
        webClient.getOptions().setPopupBlockerEnabled(true);
        webClient.setRefreshHandler(new WaitingRefreshHandler(REFRESH_HANDLER_WAIT_LIMIT)); 
    
  2. # 2 楼答案

    请尝试HtmlUnit的最新版本。我们已经修复了其间的许多内存问题。至少2.23对历史有一些修正。 此外,您现在可以控制历史记录的大小