Как заставить мягкие ссылки быть очищенными в Java?

20
задан Community 23 May 2017 в 12:19
поделиться

9 ответов

проблема: Я, может казаться, надежно не заставляю мягкие ссылки быть очищенными.

Это не уникально для SoftReferences. Из-за природы сборки "мусора" в Java, нет никакой гарантии, что что-либо, что является предметом коллекционирования мусора, будет на самом деле собрано в любом моменте времени. Даже с простым битом кода:

Object temp = new Object();
temp = null;
System.gc();

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

<час>

Тем не менее согласно Javadoc Вы заключили в кавычки, SoftReferences должен определенно быть очищен, прежде чем OutOfMemoryError брошен (на самом деле, это - весь смысл их и единственного способа, которым они отличаются от ссылок на объект по умолчанию). Это таким образом казалось бы, что существует своего рода утечка памяти в этом, Вы держите на более трудные ссылки на рассматриваемые объекты.

, Если Вы используете -XX:+HeapDumpOnOutOfMemoryError опция к JVM и затем загружаете дамп "кучи" во что-то как jhat, необходимо смочь видеть все ссылки на объекты и таким образом видеть, существуют ли какие-либо ссылки около мягких. Кроме того, можно достигнуть того же самого с профилировщиком, в то время как тест работает.

14
ответ дан 30 November 2019 в 00:09
поделиться

Существует также следующий параметр JVM для настройки, как обрабатываются мягкие ссылки:

-XX:SoftRefLRUPolicyMSPerMB=<value>

, Где 'значение' является количеством миллисекунд, мягкая ссылка останется для каждого свободного Мбита памяти. Значение по умолчанию является 1s/Mb, поэтому если объект будет только мягок достижимый, то это продлится 1 с, если только 1 МБ пространства "кучи" будет свободен.

14
ответ дан 30 November 2019 в 00:09
поделиться

Если Вы действительно хотели, можно назвать ясным () на SoftReference для очистки его.

Тем не менее, если JVM бросает OutOfMemoryError и Ваш SoftReference, еще не был очищен, то это означает, что у Вас должна быть трудная ссылка на объект где-то в другом месте. Сделать иначе делало бы недействительным контракт SoftReference. Иначе Вам никогда не гарантируют это, SoftReference очищен: пока существует все еще доступная память, JVM не должна очищать SoftReferences. С другой стороны, позволяется очистить их в следующий раз, когда это делает цикл GC, даже если это не должно.

кроме того, можно рассмотреть изучение WeakReferences, так как VM имеет тенденцию быть более агрессивным в, очищают их. Технически, VM никогда не требуется, чтобы очищать WeakReference, но он, как предполагается, чистит их в следующий раз, когда он делает цикл GC, если объект иначе считали бы мертвым. Если Ваш пытаются протестировать то, что происходит, когда Ваш кэш очищен, использование WeakReferences должно помочь Вашим записям уйти быстрее.

кроме того, помните, что оба из них зависят от JVM, делающей цикл GC. К сожалению, нет никакого способа гарантировать, что один из тех когда-либо происходит. Даже при вызове System.gc (), сборщик "мусора" может решить, что делает просто замечательный, и примите решение ничего не сделать.

2
ответ дан 30 November 2019 в 00:09
поделиться

В типичной реализации JVM (SUN) необходимо инициировать Полный GC несколько раз для убирания Softreference. Причина этого состоит в том, потому что Softreference требуют, чтобы GC сделал больше работы, потому что, например, механизма, который позволяет Вам быть уведомленными, когда объекты исправлены.

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

2
ответ дан 30 November 2019 в 00:09
поделиться

Сборка "мусора" и другие ссылки как мягкие ссылки не детерминированы это, это не действительно возможно к надежному, действительно наполняют так, чтобы мягкие ссылки были определенно очищены в той точке, таким образом, Ваш тест может судить, как yourcache реагирует. Я предложил бы, чтобы Вы моделировали ссылку, очищающуюся более определенным способом путем насмешки и т.д. - тесты будут восстанавливаемыми и более ценными, а не просто g хопи для GC для чистки ссылок. Используя последний подход действительно плохая вещь сделать, и willjust представляют дополнительные проблемы, а не помогают Вам улучшить качество своего кэша, и это сотрудничает компоненты.

1
ответ дан 30 November 2019 в 00:09
поделиться

Из документации и моего опыта я сказал бы да: у Вас должна быть ссылка где-то в другом месте.

я предложил бы использовать отладчик, который может показать Вам всем ссылки на объект (такие как Eclipse 3.4 при отладке Java 6) и просто проверить, когда OOM брошен.

0
ответ дан 30 November 2019 в 00:09
поделиться

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

0
ответ дан 30 November 2019 в 00:09
поделиться

Если у Вас есть кэш, который является Картой SoftReferences, и Вы хотите их, очистился, можно просто очистить () карту, и они будут все очищены (включая их ссылки)

-2
ответ дан 30 November 2019 в 00:09
поделиться

Есть ли у кэшированного объекта финализатор? Финализатор создаст новые сильные ссылки на объект, поэтому даже если SoftReference очищен, память не будет освобождена до следующего цикла GC

0
ответ дан 30 November 2019 в 00:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: