Подтвердить что ты не робот

Стоимость использования слабых ссылок в Java

Кто-нибудь исследовал затраты времени выполнения, связанные с созданием и сборкой мусора Java WeakReference объектов? Существуют ли какие-либо проблемы с производительностью (например, конкуренция) для многопоточных приложений?

EDIT: Очевидно, что фактический ответ будет зависящим от JVM, но общие наблюдения также приветствуются.

РЕДАКТИРОВАТЬ 2: Если кто-то сделал некоторый бенчмаркинг производительности или может указать на некоторые результаты бенчмаркинга, это было бы идеально. (Извините, но щедрость истекло...)

4b9b3361

Ответ 1

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

Ответ 2

Я реализовал сборщик мусора Java один раз, поэтому все, что я смог выполнить, - это (слабая) нижняя граница того, что возможно.

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

Итак, результат: я бы не стал беспокоиться об этом, это не большая проблема, если вы не используете зиллионы слабых ссылок.

Самое главное, что стоимость пропорциональна количеству слабых ссылок, а не размер общей кучи.

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

Шахта была простой "стоп-миром" маркой/сборщиком мусора. Во время сбора мусора он делает определение для каждого объекта, жив ли он или нет, и устанавливает бит LIVE в заголовок объекта. Затем он проходит и освобождает все неживые объекты.

Чтобы обрабатывать слабые ссылки, вы просто добавляете следующее:

  • Игнорировать слабые ссылки при установке битов LIVE (т.е. они не вызывают бит LIVE на указанном объекте).
  • На шаге развертки добавьте специальную проверку следующим образом: если объект, который вы посещаете, находится LIVE, а он WeakReference, затем проверьте объект, который он слабо ссылается, и если этот объект не является LIVE, снимите ссылку.

Небольшие вариации этой логической работы для мягких и phantom ссылок.

Реализация здесь, если вам действительно интересно.

Ответ 3

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

public Object getSomethingExpensiveToFind() {
    if(cache.contains(EXPENSIVE_OBJ_KEY)) {
        return cache.get(EXPENSIVE_OBJ_KEY);
    }

    Object sth = obtainSomethingExpensiveToFind(); // computationally expensive
    cache.put(EXPENSIVE_OBJ_KEY, sth);
    return sth;
} 

представьте этот сценарий:

1) приложение работает с низким объемом памяти

2) GC очищает слабые ссылки, поэтому кеш также очищается

3) приложение продолжает, многие методы, такие как getSomethingExpensiveToFind(), вызывают и восстанавливают кеш

4) приложение снова работает с памятью снова

5) GC очищает ссылки на ношение, очищает кеш

6) приложение продолжает, многие методы, такие как getSomethingExpensiveToFind(), вызывают и снова восстанавливают кеш

7) и т.д.

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

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