2009-05-15 2 views
2

Чтобы выполнить какое-либо тестирование, я хотел бы проверить, как работает мое приложение, когда удаляются некоторые или все объекты, которые я хранил в кеше объектов SoftReference'd.Есть ли способ определить, доступен ли объект в Java?

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

Мое приложение однопоточное, поэтому мне не нужно беспокоиться о мягкой доступности кэшируемого объекта при его выполнении. Это также означает, что в настоящее время у меня нет механизмов блокировки. Если бы у меня это было, я мог бы использовать их для определения того, был ли объект «использован» и, следовательно, сильно доступен, но, увы, мне не нужно такой блокировки.

Один из подходов, который я попытался, заключается в создании дополнительного SoftReference для каждого объекта, хранящегося в кеше, который зарегистрирован в ReferenceQueue. Я надеялся, что при этом все объекты с минимальной достижимостью в кеше добавили бы дополнительную добавку SoftReference в очередь, поэтому все, что мне нужно было сделать, это петля над очередью и удалить эти объекты из моего кеша. Тем не менее, похоже, что GC доставляет довольные объекты с мягко достижимыми объектами в соответствующие очереди, поэтому не гарантируется, что что-то будет добавлено в очередь после завершения итерации объектов в кеше.

Одна вещь, которую я также рассмотрел, это опция -XX: SoftRefLRUPolicyMSPerMB JVM с очень маленьким значением. При разумном распределении памяти это, скорее всего, позволит мне с легкостью достичь недоступных для него объектов из кэша в тот момент, когда они будут недоступны, но мне бы очень хотелось, чтобы приложение работало нормально, пока я не получаю запрос на очистку объектов, недоступных для доступа из кэша , Как вариант JVM, я не верю, что могу изменить это значение во время работы моего приложения.

Итак, есть ли у кого-нибудь какие-либо идеи относительно того, как я могу определить, является ли объект доступным только для достижения цели (и, следовательно, его можно очистить)?

Edit: На несколько дополнительных пунктов, которые, возможно, не было ясно:

  • приложение, вероятно, будет делать полезную работу в моменты, которые я хочу, чтобы очистить их мягко ссылаться на объекты из. Поэтому я бы предпочел не пытаться заставить GC очистить объекты для меня.
  • Было бы предпочтительнее, если бы я мог выбрать, какие мягко достижимые объекты были очищены.
  • Я бы хотел, чтобы приложение запускалось нормально, то есть с использованием настроек производственной памяти. Изменение настроек в коде, которое затем можно вернуть к их производственным значениям, отлично.

ответ

0

Смешивание некоторых ответов: а Том Hawtin сказал выделить память, пока вы идете OutOfMemory, например, с этим кодом:

private void doOutOfMemory() { 
    try { 
     List<byte[]> list = new ArrayList<byte[]>(); 
     while (true) { 
      list.add(new byte[200 * 1024 * 1024]); 
     } 
    } catch (OutOfMemoryError ex) { 
    } 
} 

Если вы wan't контролировать, какие объекты будут удалены, занять прочную ссылочку на объекты, которые вы хотите сохранить.

Вы также можете использовать WeakReferences вместо и вызывать только System.gc(), чтобы очистить нет никакой гарантии, что они всегда будут очищены ...

+0

Хотя это не совсем соответствует моим требованиям, это, вероятно, я пойду. – Cyphus

1

IIRC, мягкие ссылки гарантируются (в некотором смысле), подлежащие очистке до того, как будет выброшен OutOfMemoryError. Таким образом, если вы выделяете много памяти, они должны очищаться, если объекты не привязаны сильно. (Не проверено.)

+0

Хотя это * будет * очистить кэш любых мягко ссылочных объектов, я Предпочитаю сделать это, не заполняя память - так как приложение может хорошо делать полезную работу в одно и то же время, и я не хочу влиять на ее производительность. Плюс я должен был бы провести жесткий баланс между распределением достаточной памяти, чтобы ссылка была очищена, но не настолько, что я сам вызываю ошибку OutOfMemory. Плюс это не позволяло мне выбирать, какие объекты я очищаю. – Cyphus

0

Замените систему слабых ссылок для вашей текущей мягкой справочной системы во время тестирования.

Слабая система ссылок удалит объекты без каких-либо других входящих ссылок, как только это произойдет, вместо того, чтобы ждать, пока jvm будет запускать сборку мусора.

+0

Нет, вам всегда нужно подождать, пока GC не удалит объект; но со слабым отношением он должен быть удален «как можно скорее» и с мягким отношением его следует удалить, только если у JVM заканчивается память ... – pgras

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