2010-12-01 80 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(); 
    } 

}