У нас проблемы с памятью с нашим клиентом Apache CXF, поскольку служба, к которой мы подключаемся, требует безопасности WSSE, объект порта не может использоваться для разных клиентов нашего приложения из-за того, что он не является потокобезопасным. Таким образом, мы используем пул Apache Commons pool2 для объединения количества этих объектов. Служба, с которой связывается наш клиент CXF, возвращает очень большой и сложный объект xml, и, как мы видим, использование jProfiler заключается в том, что объект-порт, который мы собираем, все еще имеет ссылки на возвращаемый комплексный объект ответа, это означает, что когда мы делаем GC, что память не освобождается, когда служба становится занятой, мы видим проблемы с памятью. Во-первых, это нормально для CXF, а во-вторых, есть ли способ сказать CXF не зависать от этих ссылок и очищать себя?
Как очень простой пример, мы используем порт после создания пула при запуске приложения
{
webServicesPT webServicesPT = clientPool.getPort(); // calls borrowObject()
try {
webServicesPT.service();
} finally {
clientPool.returnPort(webServicesPT); // calls returnObject()
}
}
Любая помощь будет оценена по достоинству.
Благодарю.
У нас была точно такая же проблема, как вы описали здесь. На самом деле интересная часть состоит в том, что с точки зрения библиотеки Apache CXF все логично. Библиотека использует WeakHashMap для хранения responseContext. Ключ, используемый на карте, - это сам объект Thread. Так как ваше приложение запускается на сервере приложений с пулами потоков, а вызовы веб-служб выполняются из разных потоков, последний ответ никогда не удаляется из ClientImpl.responseContext WeakHashMap, поскольку сам поток никогда не собирает мусор. И поскольку ваши ответы большие, память заполнена, и это выглядит как проблема утечки памяти.
Решение следующее: вы должны очистить responseContext вручную, возвращая экземпляр служебного порта в пул, используя следующий код:
ClientProxy.getClient(webServicesPT).getResponseContext().clear();