Как решить вышеуказанную проблему?
Непосредственной причиной проблемы является нехватка памяти для создания новых потоков.(Эта память не выходит из обычной кучи, поэтому изменение -Xmx
не поможет.)
Фактическая причина в том, что потоки создаются быстрее, чем они выходят.Я подозреваю , что это утверждение является корнем проблемы:
synchronized (this) {
// talk to network ...
}
Проблема в том, что this
будет экземпляром SendNotification
, который вы использовали для отправки уведомления.Если вы повторно используете этот объект, вы обнаружите, что у вас есть серьезное узкое место, из-за которого сетевые задачи выполняются по одной за раз.
В дополнение к вышеуказанной проблеме ваш подход имеет недостатки, поскольку каждый раз, когда вывызов sendNotification
, он перезаписывает состояние экземпляра SendNotification
без какой-либо синхронизации.Проще говоря, вам не следует использовать одноэлементное состояние для хранения состояния для нескольких потоков ...
Другая возможность состоит в том, что вы не используете повторно экземпляры SendNotification
и (следовательно) синхронизациюпроблемы не являются причиной проблемы.В этом случае следующая возможная причина заключается в том, что вы просто создаете новые потоки быстрее, чем сервер может их обработать.
Непосредственное решение состоит в том, чтобы использовать ограниченный пул потоков, чтобы у вас никогда не было более чем, скажем, 20 потоков активных одновременно.Существуют стандартные классы для такого рода действий.
Однако будет ограничение на скорость, с которой ваше приложение / платформа может выполнять эти задачи.Если вы превысите этот лимит в течение длительного периода, очереди вашего приложения будут накапливаться, и вы столкнетесь с проблемами.Если это вероятно, тогда вашему приложению нужна какая-то стратегия для снижения нагрузки.
Хммм ...
Похоже, что стек SSL создает поток для выполнения согласования SSLна заднем фоне.Похоже, вы открываете соединение с удаленным сервером, а затем немедленно закрываете его, ничего не читая.Возможно, этот необычный шаблон использования приводит к утечке потока согласования SSL.Попробуйте прочитать байт из потока, прежде чем закрыть его.Это может привести к тому, что текущий поток будет join
поток согласования SSL, и он не останется в подвешенном состоянии.
Если это то, что происходит, то это, вероятно, ошибка в коде Java SSLSocketImplты используешь.Вам следует обновить JVM и Tomcat, чтобы получить самые последние (и не самые последние!) Исправления безопасности, производительности и исправления ошибок.Возможно, это не решит эту проблему ... но вы все равно должны это сделать.
ОБНОВЛЕНИЕ - Поиск в Google для "утечки ошибок SSLSocketImpl" дает много попаданий.Я не нашел тот, который точно соответствует, но, тем не менее, рекомендуется обновить.