2017-03-29 6 views
1

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.

Antwort

0

Sie müssen webClient.close() nennen, oder es einfach in try-with-resources, zum Beispiel setzen:

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

    // do something 
} 

Update:

können Sie speichern die CookieManager von webClient.getCookieManager() und es auch für andere WebClient s verwenden.

+0

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

+0

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 –

+0

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