哪个是在ThreadLocal实例上强制GC的更好方法?

时间:2008-11-24 14:45:14

标签: java

哪种方法可以在ThreadLocal实例上强制执行GC?

5 个答案:

答案 0 :(得分:4)

简单回答:你不能在java中强制GC。有些人可能会发布技巧,但总而言之,你根本就不能。

嗯,实际上你可以。退出!

答案 1 :(得分:3)

简单而丑陋的回答:

System.gc();

这不保证特定对象的垃圾收集,但它会告诉VM努力执行常规垃圾收集。

具体来说,对于ThreadLocal变量,在线程终止或ThreadLocal实例不再可访问之前,变量的包含实例将不会被GC。因此,您需要终止关联的线程,或者您需要放弃对ThreadLocal变量的引用,以使System.gc()产生任何影响。

但是,您调用它的事实表明您的代码中存在更大的问题。如果你想摆脱一个对象,只是没有引用它应该就足够了。 VM会在一段时间后出现并清理你的混乱。

重复一遍:没有理由干净的代码应该明确地调用GC。

答案 2 :(得分:2)

您无法强制GC,并且在许多情况下,当您在容器中运行时,即使调用System.gc()也无济于事,因为JVM通常使用-XX:+ DisableExplicitGC进行设置。 JVM将忽略您的显式调用。

答案 3 :(得分:1)

jlibs library has a good utility class for garbage collection。您可以使用WeakReference对象的漂亮小技巧强制进行垃圾收集。

来自jlibs的

RuntimeUtil.gc()

   /**
    * 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();
     }
   }

答案 4 :(得分:1)

ThreadLocal<Object>只是一把钥匙。实际值存储在每个Thread的threadLocals弱哈希映射中,该映射将 ThreadLocal映射到 Object。< / p>

假设没有其他人在Object中拥有对ThreadLocal的引用。然后有两种方法可以将ThreadLocal值的值进行垃圾回收。首先,有简单的方法:

  1. 线程结束(在内部将其threadLocals映射设置为null)。
  2. 垃圾收集器运行,删除Thread的{​​{1}}及其中所有无法访问的ThreadLocalMap
  3. 但是如果线程仍然在运行,那么这个序列必须在你的Object被垃圾收集之前发生:

    1. 您将失去对Object
    2. 的所有引用
    3. 垃圾收集器删除ThreadLocal
    4. ThreadLocal该线程中的一些其他set()ThreadLocal从地图中删除过时的条目。所需的数量是不确定的,因为与标准ThreadLocalMap不同,WeakHashMap一次只会删除一些陈旧的条目,而且仅在ThreadLocalMap,而不是set()
    5. 垃圾收集器最终删除get()
    6. 为了缓解垃圾收集缓慢的问题,如果该线程不再需要该对象,则可以从每个Object调用ThreadLocal.remove()

相关问题