首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebSphere 8内存泄漏

WebSphere 8内存泄漏
EN

Stack Overflow用户
提问于 2021-11-02 14:28:08
回答 2查看 356关注 0票数 1

我有一个应用程序部署到Eclipse8.5(应用程序是使用java8 8/Spring4开发的),每天我都会得到许多转储文件,所以我决定使用WebSphere内存分析器来分析它,结果是:

问题是我不使用axis来调用web服务,只对Rest服务使用Jersy,对于soap服务使用默认的jdk类SoapConnection,下面是一些代码示例:对于Soap:

代码语言:javascript
复制
public String soapBind(List<ContextItem> dic, String serviceId, String urlWs, String applicationId) throws SOAPException, Exception {
    try {
        SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
        SOAPConnection soapConnection = soapConnectionFactory.createConnection();
        SOAPMessage msg = soapCall(dic, serviceId, applicationId); // Send SOAP Message to SOAP Server

        String url = urlWs;
        LOGGER.info("CALLING WS ....");
        SOAPMessage soapResponse = soapConnection.call(msg, url);

        // print SOAP Response
       
        //soapResponse.writeTo(System.out);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        soapResponse.writeTo(out);
        soapConnection.close();

        String strMsg = new String(out.toByteArray());
        LOGGER.info("Response SOAP Message: {}",strMsg);
        return strMsg;

    } catch (SOAPException ex) {
        throw ex;
    } catch (UnsupportedOperationException ex) {
        throw ex;
    } catch (Exception ex) {
        throw ex;
    }
}

休息:

代码语言:javascript
复制
Client client = Client.create();
 WebResource webResource = client
 .resource(urlFicheClientProf);
//
 ServiceContext serviceContext = this.getServiceContext();
//
ObjectMapper mapper = new ObjectMapper();

 ClientResponse response = webResource
 .queryParam("customerId", radical)
 .queryParam("serviceContext",
 URLEncoder.encode(mapper.writeValueAsString(serviceContext),
 "UTF-8"))
 .post(ClientResponse.class);

我想知道为什么内存中出现了Axis.Client,以及如何修复它。如果有人能帮我弄清楚,我会非常感激的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-13 15:46:20

使用RestTemplate而不是SOAPConnection修复内存泄漏:

代码语言:javascript
复制
   final RestTemplate restTemplate = new RestTemplate();
            final HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "text/xml");
            final HttpEntity<String> request = new HttpEntity<>(message, headers);
            final String result = restTemplate.postForObject(wsUrl, request, String.class);
            return result;
票数 0
EN

Stack Overflow用户

发布于 2021-11-25 10:42:16

关于第一个问题:为什么使用默认的JDK类Axis2时使用Apache?类SOAPConnection实际上只是API的一部分,可以有不同的实现。在您的例子中,WebSphere基于Apache提供了这个API的实现,这就是为什么您看到这些类的对象挥之不去的原因。SOAPConnection Javadocs状态:

SOAPConnection类是可选的。有些实现可能不实现这个接口,在这种情况下,对SOAPConnectionFactory.newInstance()的调用(参见下面)将抛出一个UnsupportedOperationException。

关于你问题的第二部分,我有一个假设。在Javadocs中,我无法找到对SOAPConnection.close()的调用是否是强制性的,但是通常带有close()方法的资源类确实需要清理,否则它们会创建内存或其他资源泄漏。您的代码确实调用了close(),但是如果在关闭连接之前某个地方发生异常,则执行将直接跳转到catch (.)并且连接将不会被清除,从而造成内存泄漏。也许每次SOAP调用抛出异常时都会发生这种情况,并且泄漏了您正在观察的内存。

您可以通过使用这里描述的尝试-资源关闭模式来解决这个问题:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html在代码中尝试以下更改。

编辑

代码语言:javascript
复制
public String soapBind(List<ContextItem> dic, String serviceId, String urlWs, String applicationId) throws SOAPException, Exception {
    try {
        SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
        try (MySOAPConnection mySoapConnection = new MySOAPConnection(soapConnectionFactory)) {
            SOAPConnection soapConnection = mySoapConnection.connection;
            SOAPMessage msg = soapCall(dic, serviceId, applicationId); // Send SOAP Message to SOAP Server

            String url = urlWs;
            LOGGER.info("CALLING WS ....");
            SOAPMessage soapResponse = soapConnection.call(msg, url);

            // print SOAP Response
           
            //soapResponse.writeTo(System.out);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            soapResponse.writeTo(out);
            
            String strMsg = new String(out.toByteArray());
            LOGGER.info("Response SOAP Message: {}",strMsg);
            return strMsg;
        }
    } catch (SOAPException ex) {
        throw ex;
    } catch (UnsupportedOperationException ex) {
        throw ex;
    } catch (Exception ex) {
        throw ex;
    }
}

public class MySOAPConnection implements AutoCloseable {

    public final SOAPConnection connection;
    
    public MySOAPConnection(SOAPConnectionFactory soapConnectionFactory)
    {
        this.connection = soapConnectionFactory.createConnection();
    }
    
    @Override
    public void close() throws Exception {
        this.connection.close();            
    }
}

请注意,当您使用try-resource时,不应该显式地调用close()方法,否则您将得到双close()!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69812071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档