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

问题是我不使用axis来调用web服务,只对Rest服务使用Jersy,对于soap服务使用默认的jdk类SoapConnection,下面是一些代码示例:对于Soap:
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;
}
}休息:
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,以及如何修复它。如果有人能帮我弄清楚,我会非常感激的。
发布于 2021-12-13 15:46:20
使用RestTemplate而不是SOAPConnection修复内存泄漏:
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;发布于 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在代码中尝试以下更改。
编辑
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()!
https://stackoverflow.com/questions/69812071
复制相似问题