Ich habe den folgenden Code:Java Htmlunit Speicherverlust
for (int i = 0; i < list.size(); i++) {
navigate(list.get(i));
}
Und für die Navigate-Methode:
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;
HtmlPage
und WebClient
wurden global deklariert.
Um es in die richtige Perspektive zu bringen, fülle ich ein Formular aus, drücke OK, drücke Bestätigen und ich werde zu meiner Startseite weitergeleitet, damit ich den Vorgang wiederhole. Das Problem ist, dass meine Anwendung die gesamte Speicher auffressen wird. Und später wird dies eine Heap-Ausnahme auslösen.
Wenn ich die Web-Fenster zähle, sehe ich, dass diese Nummer wächst und niemals abnimmt. Viele andere Themen zu diesem Speicherleck legen nahe, dass ich die Methode .CloseAllWindows()
aufrufen muss, aber diese Funktion wurde entfernt.
Derzeit verwende ich HtmlUnit 2.25.
Habe ich beim Umleiten einen Fehler gemacht, damit ältere Fenster im Hintergrund bleiben?
NEUFASSUNG:
Schaffung eines neuen WebClient-Methode:
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;
}
Schleife gleich geblieben. Navigate-Methode:
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();
...
}
Speicher wird mit jedem Methodenaufruf immer noch erhöht.
Vielen Dank für Ihre Antwort! Dadurch wird meine Sitzung korrekt beendet? Weil ich in einer Sitzung weiter navigieren möchte. Dies, weil ich mich anmelden muss, bevor ich diese Anfangsseite erreiche, und ich möchte mich nicht für jeden Sendeauftrag anmelden. – Schippert
Ja, dies schließt die Sitzung. Sie können den WebClient zwischenspeichern, aber stellen Sie sicher, dass Sie ihn schließen und alle z. 100 Anfrage –
Das Problem ist, dass ich eine Heap-Ausnahme nach 5 navigieren Anrufe, weil dann habe ich mehr als 100 Web-Fenster geöffnet. Ist es möglich, diese Anzahl zu reduzieren? Oder ist es möglich, nur die Sitzung und nicht die Web-Fenster zu speichern? – Schippert