2013-07-15 2 views
-2

В одном из наших приложений Java мы получили OutOfMemoryError:GC Overhead limit exceeded.OutOfMemoryError: GC Верхний предел превышен

Мы использовали HashMaps в someplaces для хранения некоторых журналов data.From мы можем определить, что я его воспроизводящий на том же месте.

Я хотел спросить, тратит ли сборщик мусора больше времени на очистку хэшмапов?

После глядя на код (я не могу поделиться здесь), я обнаружил, что, что есть HashMap создается как

Hashmap topo = new HashMap();

но HashMap никогда не используется. Является ли это своего рода утечкой памяти в моем приложении?

Если этот Hashmap создан внутри метода, который выполняет некоторую обработку и не используется в другом месте, этот метод также доступен для моих нескольких потоков. Например, в таком случае это повлияет, создавая Hashmap, как указано выше, сборщик мусора потратить больше времени на восстановление кучи и выбросить OOME.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

+2

Если ссылка 'topo' не выходит за пределы области, в которой она была объявлена, то нет, это не способствует созданию утечки памяти. –

+0

Будет ли сборщик мусора сталкиваться с проблемами при очистке этих хэш-карт? Если предположить, что существует большое количество этих хэш-карт – Saurav

+2

Используйте профилировщик, чтобы посмотреть на потребление памяти или увеличить максимальный объем памяти. Если вы не измеряете свою программу, вы просто угадываете. Использование большого количества HashMaps не подходит для производительности/памяти, но это может быть не самая большая проблема. –

ответ

0

n one of our java application we have got OutOfMemoryError:GC Overhead limit exceeded. We have used HashMaps in someplaces for storing some data.From logs we can I identify that its reproducing at the same place.

Если Hashmap просто когда-либо строительство и скорее всего помечена как статическая, а значит, вы продолжать добавлять вещи к этому HashMap и никогда не удалять. Тогда в один прекрасный день это приведет к OutOfMemoryError.

I wanted to ask if Garbage Collector spends more time in clearing up the hashmaps?

Сборщик мусора проводит время на объектах, которые не ссылаются, слабо ссылки, мягкие ссылки. Где бы он ни находил такие объекты, в зависимости от необходимости он их очищает.

Upon looking at the code(i cant share here), I have found that that there is a Hashmap created like Hashmap topo = new HashMap(); , but this hashmap is never used. Is this a kind of memory leak in my application ?

if this Hashmap is created inside a method which is doing some processing and it is not used elsewhere also this method is accessed my multiple threads say 20 . Then in such a case would it impact,creating Hashmap as above, Garbage collector to spend more time in recovering heap and throw OOME.

Если HashMap локально в methid и метод выходит после выполнения некоторой обработки, то это должно быть мусор, как только метод выход. Поскольку hashmap является локальным для метода, поэтому каждый поток будет иметь отдельную копию этой карты, и как только поток завершит выполнение метода, карта имеет право на GC.

+0

Спасибо ... Предположим, есть ли большое количество таких неиспользуемых Hashmaps, Will Collector потратит некоторое время на восстановление кучи, и возможно ли, что он выбросит OOME. – Saurav

+0

@Saurav Простые ссылки на пустые hashmaps вряд ли съедят значительное пространство кучи. –

+0

Короткий ответ: вы пропадаете в другом месте. Вы будете хранить или накапливать фактические данные за время жизни приложения. Временная HashMap, локальная по отношению к методу и не связанная с внешней средой, не будет проблемой. –

0

Вам необходимо найти объекты с длительным сроком службы & структуры, которые могут быть реальной проблемой, а не дико хвататься за любую идею незнакомого менеджера о потенциальной проблеме.

См:

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

Обратите внимание, что внутренние классы (слушатели, наблюдатели) могут захватывать ссылки на их область с областью &, чтобы предотвратить их отсутствие на GC.

+0

Я собрал heapDump в OOME и обнаружил, что LinkedBlockingQueue, который мы использовали в ThreadpoolExecutor, занимает 93% от общей кучи, выделенной для процесса. Общая выделенная куча - Xmx3500m. Это происходит потому, что задачи выполняются намного быстрее, чем потоки в пуле, выполняющие его? Может ли эта ошибка java быть ответственна за это: http://bugs.sun.com/view_bug.do?bug_id=6806875. Как справиться с такой ситуацией? – Saurav

+0

Эта ошибка JDK не должна вызывать OOME - она ​​должна просто ухудшить производительность и вызвать «полный GC», если в противном случае «младший GC» был бы достаточным. –

+0

Почему вы не добавляете точки ввода (добавления) и выхода (удаления) для LinkedBlockingQueue и не подсчитываете, сколько задач входит/выдает и ставит в очередь? Запишите это и посмотрите, так ли это, и если да, тогда вы можете заглянуть в * почему * так много задач в очереди. –

0

Please let me know if you need some more details.

Вы нужны еще некоторые детали.Вам необходимо профилировать приложение, чтобы узнать, какие объекты потребляют кучу пространства.

Затем, если некоторые из значимых объектов больше не используются вашим приложением, у вас есть утечка памяти. Посмотрите на ссылки на эти объекты, чтобы узнать, почему они все еще хранятся в памяти, когда они больше не полезны, а затем модифицируют ваш код, чтобы больше не хранить эти ссылки.

Кроме того, вы можете обнаружить, что все объекты в памяти - это то, что вы ожидаете от своего рабочего набора. Затем либо вам нужно увеличить размер кучи, либо реорганизовать ваше приложение на работу с меньшим рабочим набором (например, потоковые события по одному, а не чтение всего списка, сохранение последних данных в базе данных, а не памяти и т. Д.).).

+0

Я собрал heapDump в OOME и обнаружил, что LinkedBlockingQueue, который мы использовали в ThreadpoolExecutor, занимает 93% от общей кучи, выделенной для процесса. Общая выделенная куча - Xmx3500m. Это происходит потому, что задачи выполняются намного быстрее, чем потоки в пуле, выполняющие его? Может ли эта ошибка java быть ответственна за это: http://bugs.sun.com/view_bug.do?bug_id=6806875. Как справиться с такой ситуацией? – Saurav

+0

@Saurav Опять же, это то, что вам нужно будет посмотреть, но, похоже, вы слишком быстро добавляете задания.Выполняются ли в очереди все задачи, ожидающие выполнения? Если да, то действительно вы создали данные на 3,3 ГБ, которые должны быть запущены в будущем, но еще не были. В этом случае нет простого ответа; либо вы дросселируете скорость, с которой создаются задачи, увеличиваете скорость обработки, либо увеличиваете размер кучи. Какой из них вы выберете, будет зависеть от ваших требований и деталей вашей ситуации. –

+0

Чтобы решить проблему, я использовал ArrayBlockingQueue (50), и в потоковом пуле есть максимум 20 потоков. Поскольку я использовал ограниченную очередь, последующая задача будет отклонена, поэтому используется RejectedExecutionHandler для обработки отклоненных задач и обработчика по умолчанию политика CallerRunsPolicy, так как я не хочу потерять задачу. Я с нетерпением жду тестирования этого решения. Пожалуйста, предоставьте свои комментарии. Будет ли это полезно? – Saurav

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