哪种方法可以在ThreadLocal实例上强制执行GC?
答案 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的 /**
* 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值的值进行垃圾回收。首先,有简单的方法:
null
)。Thread
的{{1}}及其中所有无法访问的ThreadLocalMap
。但是如果线程仍然在运行,那么这个序列必须在你的Object
被垃圾收集之前发生:
Object
。ThreadLocal
。ThreadLocal
该线程中的一些其他set()
,ThreadLocal
从地图中删除过时的条目。所需的数量是不确定的,因为与标准ThreadLocalMap
不同,WeakHashMap
一次只会删除一些陈旧的条目,而且仅在ThreadLocalMap
,而不是set()
。get()
。为了缓解垃圾收集缓慢的问题,如果该线程不再需要该对象,则可以从每个Object
调用ThreadLocal.remove()
。