2010-12-01 89 views
3

我有一個java webobjects應用程序,它在Red Hat上運行時顯示內存泄漏問題,但在Mac OS X上運行時沒有這樣的問題。JVM類似。來自Sun在Red Hat上運行時發生Java內存泄漏但在Mac OS X上沒有內存泄漏

從蘋果 紅帽EL 5.0使用

的Mac OS X 10.6.5使用Java 1.6.0_22 64位Java 1.6.0_20 64位我的配置,否則堆轉儲時跑出內存,並使用eclipse內存分析工具分析這個問題,這表明問題出現在創建向Web服務發送HTTP請求的線程的代碼的一部分中。創建線程的原因是爲了實現請求的超時,因爲Web服務有時不可用。

有沒有人有任何想法?

WOHTTPConnection connection = new WOHTTPConnection(host, port); 
    WORequest request = new WORequest(strMethod, strQuery, strHttpVersion, nsdHeader, content, null); 

    WebServiceRequester theRequester = new WebServiceRequester(connection, request); 
    Thread requestThread = new Thread(theRequester); 
    requestThread.start(); 
    try { 
      requestThread.join(intTimeoutSend); //timeout in milliseconds = 10000 
      if (requestThread.isAlive()) { 
       requestThread.interrupt(); 
      } 
    } catch(InterruptedException e) { 

    } 
    requestThread = null; 
    if(!theRequester.getTfSent()) { 
      return null; 
    } 
    WOResponse response = connection.readResponse(); 

...

class WebServiceRequester implements Runnable { 

    private WORequest theRequest; 
    private WOHTTPConnection theConnection; 
    private boolean tfSent = false; 

    public WebServiceRequester(WOHTTPConnection c, WORequest r) { 
     theConnection = c; 
     theRequest = r; 
    } 

    public void run() { 
     tfSent = theConnection.sendRequest(theRequest); 
    } 

    public boolean getTfSent() { 
     return tfSent; 
    } 
} 

編輯:所報告的日食內存分析工具泄露類名稱:

1,296 instances of "java.lang.Thread", loaded by "<system class loader>" occupy 111,947,632 (43.21%) bytes. 
1,292 instances of "er.extensions.eof.ERXEC", loaded by "java.net.URLClassLoader @ 0x2aaab375b7c0" occupy 37,478,352 (14.46%) bytes. 
1,280 instances of "er.extensions.appserver.ERXRequest", loaded by "java.net.URLClassLoader @ 0x2aaab375b7c0" occupy 27,297,992 (10.54%) bytes. 
+0

如果你擺脫了線的就讓它正常運行,將內存泄漏消失的代碼?如果沒有,那麼這不是你的問題。 – 2010-12-01 03:39:44

+0

檢查,它沒有離開:( – Rudiger 2010-12-01 04:42:09

+1

什麼是泄露的類名? – 2010-12-01 04:46:43

回答

1

聽說WOHTTPConnection已損壞,不應使用。 WOHTTPConnection不會爲您提供關閉連接的可靠方法。在其他方面也不可靠。

的解決方案是重寫使用Apache的HttpClient HttpComponents

1

你需要關閉WOHTTPConnection處理? (我不熟悉那個API ......)。

隨訪

經過了進去,看起來像connection.readResponse()關閉連接,所以我並不需要做手工。

@Rudiger - 你是假設調用connection.readResponse()總是成功。如果問題是拋出一個沒有得到報告的異常會怎麼樣? (默認行爲是默默地忽略在子線程上拋出的錯誤。)

我想你應該關閉finally塊中的連接句柄......以防萬一。

還是更好,溝槽WOHTTPConnection完全。

1

我認爲問題在於Thread.interrupt實際上並不會停止您的線程。如果JVM運行,JVM永遠不會清理它。

我會爲您的線程添加一個closeConnection方法,並嘗試調用該方法,而不是或除了您的Thread.interrupt調用之外。您可能需要稍作修改,但這個想法是明確停止正在保持線程中運行的IO:

WOHTTPConnection connection = new WOHTTPConnection(host, port); 
WORequest request = new WORequest(strMethod, strQuery, strHttpVersion, nsdHeader, content, null); 

WebServiceRequester theRequester = new WebServiceRequester(connection, request); 
Thread requestThread = new Thread(theRequester); 
requestThread.start(); 
try { 
     requestThread.join(intTimeoutSend); //timeout in milliseconds = 10000 
     if (requestThread.isAlive()) { 
      requestThread.closeConnection(); 
      requestThread.interrupt(); 
     } 
} catch(InterruptedException e) { 

} 
requestThread = null; 
if(!theRequester.getTfSent()) { 
     return null; 
} 
WOResponse response = connection.readResponse(); 

...

class WebServiceRequester implements Runnable { 

    private WORequest theRequest; 
    private WOHTTPConnection theConnection; 
    private boolean tfSent = false; 

    public WebServiceRequester(WOHTTPConnection c, WORequest r) { 
     theConnection = c; 
     theRequest = r; 
    } 

    public void run() { 
     tfSent = theConnection.sendRequest(theRequest); 
    } 

    public boolean getTfSent() { 
     return tfSent; 
    } 

    public void closeConnection() { 
     this.theConnection.close(); 
    } 

}