是的,在实际收集垃圾后清除密钥
是的,WeakHashMap
确实清除了碎屑。已进入垃圾收集的键不再以大小报告。但是您必须等待垃圾收集实际发生。
似乎您对要进行垃圾收集的对象不正确。也许您的对象成为垃圾收集的候选对象,但尚未被收集。尝试调用垃圾收集器并等待它完成。但请记住,对 JVM 的调用System.gc()
只是对 JVM 的建议,可能会被忽略,具体取决于您的 JVM 实现和当前运行时场景。
这是一个完整的示例应用程序。请注意,无论是调用还是让对象超出范围,Set
报告都会减少。size
Set::remove
package com.basilbourque.example;
import java.util.Collections;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
public class WeakHashMapExercise {
public static void main ( String[] args ) {
WeakHashMapExercise app = new WeakHashMapExercise();
app.doIt();
}
private void doIt ( ) {
Set < UUID > set =
Collections.synchronizedSet(
Collections.newSetFromMap(
new WeakHashMap <>()
)
);
UUID uuid1 = UUID.fromString( "a8ee1e34-cead-11e8-a8d5-f2801f1b9fd1" );
UUID uuid2 = UUID.fromString( "39bda2b4-5885-4f56-a900-411a49beebac" );
UUID uuid3 = UUID.fromString( "0b630385-0452-4b96-9238-20cdce37cf55" );
UUID uuid4 = UUID.fromString( "98d2bacf-3f7f-4ea0-9c17-c91f6702322c" );
System.out.println( "Size before adding: " + set.size() );
set.add( uuid1 );
set.add( uuid2 );
set.add( uuid3 );
set.add( uuid4 );
System.out.println( "Size after adding 4 items: " + set.size() ); // Expect 4.
set.remove( uuid3 );
System.out.println( "Size after removing item # 3: " + set.size() ); // Expect 3.
uuid2 = null; // Release that UUID to garbage-collection.
// That released object may still appear in our `Set` until garbage collection actually executes.
System.gc(); // Ask the JVM to run the garbage-collection. Only a suggestion, may be ignored.
try {
Thread.sleep( 1_000 ); // Wait a moment, just for the heck of it.
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println( "Size after making garbage of item # 2: " + set.size() ); // Expect 2.
for ( UUID uuid : set ) {
System.out.println( uuid.toString() );
}
}
}
请参阅在 IdeOne.com 上实时运行的代码。
添加前尺寸:0
添加 4 件后尺寸:4
移除项目 #3 后的尺寸:3
制作项目#2的垃圾后的尺寸:2
在我的情况下,使用来自Azul Systems的基于OpenJDK的Zulu JVM的Java 10.0.2版本,垃圾收集器似乎确实应我的请求激活。如果我注释掉延迟一秒钟或调用,那么最后报告的大小仍然是而不是预期的。System.gc
3
2
在 IdeOne.com 上实时运行此代码时,您甚至可以看到这种行为。请注意下面的最后一项是如何,3
但上面是2
。
添加前尺寸:0
添加 4 件后尺寸:4
移除项目 #3 后的尺寸:3
制作项目#2的垃圾后的尺寸:3