我们的Apache CXF客户端存在内存问题,因为我们连接的服务需要WSSE安全性,因为不是线程安全的,所以不能在我们的应用程序的不同客户端之间共享端口对象。 所以我们使用Apache Commons pool2来汇集x个这些对象。 我们的CXF客户端连接的服务返回一个非常大且复杂的xml对象,我们似乎注意到使用jProfiler 我们正在汇集的端口对象仍然引用了返回的复杂响应对象,这意味着当我们执行GC时内存未被释放时,当服务忙碌时我们会看到内存问题。 首先是CXF的正常情况,其次是有办法告诉CXF不要依赖这些引用并自行清理吗?
作为一个非常基本的例子,这是我们在应用程序启动时创建池后如何使用端口
{
webServicesPT webServicesPT = clientPool.getPort(); // calls borrowObject()
try {
webServicesPT.service();
} finally {
clientPool.returnPort(webServicesPT); // calls returnObject()
}
}
任何帮助都将不胜感激。
感谢。
答案 0 :(得分:2)
我们遇到了与您在此处描述的完全相同的问题。实际上有趣的是,从Apache CXF库的角度来看,一切都是合乎逻辑的。该库使用WeakHashMap存储responseContext。地图中使用的键是Thread对象本身。因此,当您的应用程序在具有线程池的应用服务器上运行并且Web服务调用来自不同的线程时,最后的响应永远不会从ClientImpl.responseContext WeakHashMap中删除,因为线程本身永远不会被垃圾回收。并且由于您的响应很大,内存已经填满,而且看起来存在内存泄漏问题。
解决方案如下:使用以下代码将服务端口实例返回池时,必须手动清除responseContext:
ClientProxy.getClient(webServicesPT).getResponseContext().clear();