Почему GC не собирает мои объекты?

У меня есть Java-программа, которая продолжает звонить java.util.zip сжать / распаковать данные. Он исчерпывает память в течение нескольких секунд. У меня был дамп памяти с jmap и я просматриваю это с jhat,

Финализатор сводных шоу Total instances pending finalization: 0, Если я правильно понимаю, у меня нет объектов, которые (1) имеют метод finalize(), (2) помечены GC и (3) ожидают завершения. Это кажется хорошим.

Когда я смотрю на конкретный объект, единственная ссылка на этот объект java.lang.ref.Finalizer, Объект Finalizer создается для каждого объекта, у которого есть метод finalize(), независимо от того, Ged-объект или нет. Так что, похоже, ничто не мешает этому Deflater объект для GC'ed.

Объект в 0x7f4aeb7a35d0

экземпляр java.util.zip.Deflater@0x7f4aeb7a35d0 (51 байт)

Ссылки на этот объект:

java.lang.ref.Finalizer@0x7f4aeb8607c8 (64 байта): полевой референт

Программа приостановлена ​​в ходе выполнения System.in.read(), Использование памяти не снижается через некоторое время.

ОБНОВИТЬ:

Я должен сделать это ясно. Дамп памяти показывает, что многие объекты не были GC-объектами, но никакие другие объекты (кроме объектов Finalizer) не ссылались на них. Я пытаюсь выяснить, почему они не были GC'ed.

5 ответов

Решение

Вы уверены, что закрыли поток и вызвали end на дефлят? Извините, если это упрощенное предложение, которое вы уже попробовали, но было много жалоб на утечку памяти при использовании Deflater когда не сразу вызывая end на это, например:

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

Поскольку вы написали, вы не используете Deflator напрямую, но через Apache Thrift, попытайтесь определить, какой метод в этой библиотеке отвечает за завершение дефлятора, и убедитесь, что вы вызвали этот метод.

Основная проблема в том, что вы не освобождаете объекты из кучи C. Многие классы в java.util.zip используют Deflater, Deflater поддерживает ссылку на данные в куче Си. Ваш код, вероятно, не звонитclose() на ZipOutputStream или же DeflaterOutputStreamили это не звонит end() на Deflater,

(Если вы передаете свой собственный Deflater в ZipOutputStream или же DeflaterOutputStream, вы несете ответственность за звонки end() на Дефлатере.)

GC имеет ограниченную помощь в вашем случае, потому что поток (ы) должен быть разыменован и в конечном итоге завершен. Это может занять несколько циклов ГХ. Я столкнулся с подобной проблемой с Jetty и предложил исправить ее.

Добавление к ответу Мариана-Даниэля Крачиунеску

У меня была такая проблема с другим типом использования.

Решение, которое я нашел, заключается в следующем:

  • Поместите объект на карту или куда-нибудь, где вы можете легко опустить его ссылку
  • Поместите также объект в WeakReference для его использования
  • Используйте вашу ссылку как обычно
  • Удалить ссылку с карты, где больше не используется

Будьте осторожны с унаследованными ссылками

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

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

Полезная ссылка

Вы должны прочитать (если это еще не сделано) этот пост о WeakReferences: понимание справочных классов Java: SoftReference, WeakReference и PhantomReference

Прежде всего, прежде чем думать об утечке памяти, мы должны попытаться понять, является ли требование к памяти нормальным для обработки, которую вы выполняете. Какой размер памяти доступен для JVM, т. Е. -XmX. Если вы увеличиваете размер памяти или уменьшаете размер обрабатываемого файла, это работает?

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

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html http://weblogs.java.net/blog/2006/05/04/understanding-weak -Рекомендации

Другие вопросы по тегам