2008-11-24 3 views

ответ

4

Простой ответ: вы не можете заставить GC в java. Некоторые могут писать трюки, но в целом вы просто не можете.

Ну, на самом деле вы можете. С выходом!

+0

На самом деле вы можете заставить gc() [проверить мой ответ на эту тему] используя слабые ссылки и не покидая;) – shams 2011-08-02 16:16:43

3

Простой и некрасиво ответ:

System.gc(); 

Это не гарантирует, сбор мусора конкретного объекта, но он будет говорить VM, чтобы приложить усилия для выполнения общего сбора мусора.

В частности, для переменной ThreadLocal содержащийся экземпляр переменной не будет GC'd, пока нить не исчезнет, ​​или экземпляр ThreadLocal больше не будет доступен. Таким образом, вам нужно будет убить связанный поток, или вам нужно будет отменить свои ссылки на переменную ThreadLocal, чтобы System.gc() имел какой-либо эффект.

Однако тот факт, что вы вызываете это, указывает на большую проблему в вашем коде. Если вы хотите избавиться от объекта, просто не имея ссылок на него, должно быть достаточно. VM придет через некоторое время и очистит ваш беспорядок.

Повторить: нет причин, по которым чистый код должен быть явно вызван GC.

+0

Не правда. ThreadLocal реализуется как слабая карта хэша. Сборщик мусора не может вернуть память, если вы явно не заставляете это делать это. – user26365 2008-11-24 20:13:29

+1

Насколько мне известно, нет специального «принудительного» контракта на сбор мусора с WeakHashMap (или с любым объектом, если на то пошло). Как правило, сборщик мусора будет освобождать место в слабой карте хэша всякий раз, когда ключ больше не используется в «обычном использовании». – 2008-11-24 22:10:26

1

jlibs library has a good utility class for garbage collection. Вы можете принудительно собрать сбор мусора с помощью отличного маленького трюка с объектами WeakReference.

RuntimeUtil.gc() из jlibs:

/** 
    * This method guarantees that garbage collection is 
    * done unlike <code>{@link System#gc()}</code> 
    */ 
    public static void gc() { 
    Object obj = new Object(); 
    WeakReference ref = new WeakReference<Object>(obj); 
    obj = null; 
    while(ref.get() != null) { 
     System.gc(); 
    } 
    } 
2

Вы не можете заставить GC и во многих случаях, когда вы бежите в контейнере, даже вызывая System.gc() не поможет, так как виртуальная машина, как правило, устанавливается с - XX: + DisableExplicitGC. JVM будет игнорировать ваши явные вызовы.

1

A ThreadLocal<Object> - всего лишь ключ. Фактические значения сохраняются в каждой строке Thread. Слабая карта хэша, которая отображает слабыйThreadLocal до сильныйObject.

Предположим, что ни у кого другого нет ссылки на Object в ThreadLocal. Тогда есть два способа оценить ценность значения ThreadLocal для сбора мусора. Во-первых, есть простой способ:

  1. Резьбовые концы (внутри установки его threadLocals карту в null).
  2. Мусороуборочный комбайн работает, удаляя ThreadThreadLocalMap и все недостижимые Object s внутри него.

Но если поток все еще работает, то эта последовательность должна произойти прежде, чем ваш Object может быть мусор:

  1. Вы теряете все ссылки на ThreadLocal.
  2. Сборщик мусора удаляет ThreadLocal.
  3. Вы set() некоторое количество других ThreadLocal s в пределах этой темы, а ThreadLocalMap удаляет простую запись с карты. Необходимое число является недетерминированным, поскольку в отличие от стандарта WeakHashMap, ThreadLocalMap только выдает несколько устаревших записей за раз и только на set(), а не get().
  4. Сборщик мусора, наконец, удаляет Object.

Чтобы смягчить проблему медленной сборки мусора, вы можете позвонить ThreadLocal.remove() из каждого Thread, если этот поток не нужен объект больше.

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