2010-03-12 3 views
2

Мне сложно отслеживать это, поскольку профайлер продолжает сбой (ошибка хот-спота). Прежде чем я углубится в это, я хотел бы знать, есть ли у меня проблема или нет :-)Ошибка утечки памяти ExecutorService

У меня есть несколько пулов потоков, созданных через: Executors.newFixedThreadPool (10); Нити подключаются к различным веб-сайтам, и иногда я получаю отказ в подключении и завершаю исключение.

Когда я позже позвонил в Future.get(), чтобы получить результат, он поймает исключение ExecutionException, которое обертывает исключение, которое было выбрано, когда соединение не было выполнено.

Программа использует довольно постоянное количество памяти до момента, когда исключаются исключения (они, как правило, происходят в партиях, когда определенный сайт перегружен). После этой точки память снова остается постоянной, но на более высоком уровне.

Итак, мой вопрос связан с тем, как поведение памяти (сообщается «сверху» в Unix) ожидается, потому что исключения только что вызвали что-то или у меня, вероятно, есть настоящая утечка, которую мне нужно будет отслеживать? Кроме того, когда Future.get() выдает исключение, есть что-то еще, что мне нужно сделать, кроме того, чтобы поймать исключение (например, вызвать на нем Future.cancel())?

РЕДАКТИРОВАТЬ: так что я действительно просмотрел с помощью нескольких инструментов, и с точки зрения Java нет ничего разумного в утечке памяти. Я буду играть с другим кодом, который живет долгое время, и через какое-то время выдает исключение и выясняет, увеличивается ли память, указанная в «верхнем». Похоже, это может быть какая-то странность.

+0

Не имея ответа на вопрос о проблеме с исполнителем, могу сказать, что верхняя часть не является полезным способом диагностики проблем памяти в JVM (посмотрите параметры -Xmx и -Xms). Память, восстановленная в JVM на GC, не обязательно появится за ее пределами (я не думаю, что она когда-нибудь появится, но я не совсем уверен в этом). Для проверки памяти используйте Runtime.getRuntime(). TotalMemory() - Runtime.getRuntime(). FreeMemory(). –

ответ

1

Выполняется ли ваш Java-процесс на самом деле с исключением java.lang.OutOfMemoryError? Если нет, то вряд ли у вас будет утечка. Конечно, вы всегда можете подключиться к процессу Java с помощью JConsole, захватить кучу кучи и открыть его в бесплатном инструменте, таком как HPjmeter, чтобы узнать действительно быстро.

+0

Он не работает достаточно долго, чтобы это произошло, и память постоянна. Скажем, «топ» сообщает, что 550 мегабайт в использовании, затем он скачет до 750 мегабайт и обратно до 550 мегабайт через некоторое время (200 из Java). После исключения случается, что он прыгает на 1 концерт и, кажется, остается там. Интересно то, что даже если случается больше исключений, он остается там, поэтому, думая об этом, возможно, исключения просто приводят к возникновению какой-то постоянной величины. Я посмотрю на jmeter в дополнение к визуальному vm, который я собираюсь использовать. – TofuBeer

0

JVM начнется с Xms amout кучи, а затем возьмет больше от системы до Xmx. Даже если GC освобождает кучу в JVM, процесс java держится за кучу, которую он схватил из ОС (поэтому в top она никогда не уменьшается) (Опыт работы с Sun JVM (Java1.5/6) на Redhat Linux) ,

Возможно, что куча освобождена и доступна, но она не выпущена для ОС и в top java, похоже, использует много кучи.

Вы можете использовать visualvm, инструмент, который поставляется с JDK. Просто запустите приложение. в течение длительного времени подключите инструмент и посмотрите на кумулятивную телеметрию. Если он продолжает расти, это может быть утечка памяти. Вы также можете взять кучу кучи с помощью этого инструмента и посмотреть, какие объекты накапливаются.

Смежные вопросы