использование статического словаря в качестве кеша может привести к проблеме утечки? - PullRequest
1 голос
/ 21 июля 2010

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

В качестве БД я использую хэш-карты, хэш-наборы и т. Д. (Загружено около 20 МБ данных). Эти карты, наборы перезагружаются один раз в 10 минут. Существует огромное количество одновременных запросов. Я читал, что GC передает объекты, которые не были собраны за период времени / цикл, поколению (старое и постоянное поколения), которое менее проверено или собрано мусором. Я думаю, что мое использование для статических карт, наборов вызывает у меня проблему утечки. Что ты думаешь?

Ответы [ 5 ]

2 голосов
/ 21 июля 2010

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

Реализация Map на основе хеш-таблицы со слабым ключи .Запись в WeakHashMap будет автоматически удалена, если ее ключ больше не используется.Точнее говоря, наличие сопоставления для данного ключа не помешает тому, чтобы ключ был отброшен сборщиком мусора, то есть сделан финализируемым, финализированным и затем восстановленным.Когда ключ отбрасывается, его запись эффективно удаляется с карты, поэтому этот класс ведет себя несколько иначе, чем другие реализации Map.

К сожалению, в Java6, похоже, в стандартной библиотеке нет WeakHashSet, но в сети можно найти несколько реализаций.

1 голос
/ 21 июля 2010

Это не утечка, если вы удалили все ссылки на него. Если вы полностью очищаете свою карту, то это не источник утечки. Вы должны учитывать тот факт, что JVM выбирает не принадлежащее GC поколение очень часто, как не относящееся к вам - все, что имеет значение, это то, что у вас нет ссылки на него, поэтому JVM может GC это, если хочет.

Существуют различные стратегии, которые JVM могут использовать для управления GC, поэтому я говорю здесь в общих чертах, а не в деталях, но места с использованием GCing, как правило, очень дороги и оказывают большое влияние на приложение, поэтому JVM выбирает не делать это часто вообще.

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

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

1 голос
/ 21 июля 2010

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

Могу поспорить, что вы не очищаете это должным образом. Часть GC работает нормально, я бы не беспокоился, что это проблема.

0 голосов
/ 21 июля 2010

Я предлагаю вам проверить содержимое кучи, используя дамп кучи и анализатор кучи (например, JVisualVM ).Это поможет вам найти подозреваемых в утечке.Тот факт, что старое поколение собирается реже, не означает, что утечка большей памяти;помните, что, хотя он может казаться заполненным, только часть его представляет живые объекты, а другая часть очищается следующим основным GC.Как говорили другие, проблема может быть в неполной очистке статических коллекций.

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

0 голосов
/ 21 июля 2010

Вы также можете рассмотреть возможность использования WeakReference , если у вас есть какой-то способ возврата к реальным данным, если часть вашего кэша отредактирована GC, но затем потребуется.

...