返回信息流在看Java编程思想时,有这样一个关于WeakHashMap样例代码
import java.util.WeakHashMap;
class Element {
private String ident;
public Element(String id) { ident = id; }
public String toString() { return ident; }
public int hashCode() { return ident.hashCode(); }
public boolean equals(Object r) {
return r instanceof Element &&
ident.equals(((Element)r).ident);
}
protected void finalize() {
System.out.println("Finalizing " +
getClass().getSimpleName() + " " + ident);
}
}
class Key extends Element {
public Key(String id) { super(id); }
}
class Value extends Element {
public Value(String id) { super(id); }
}
public class CanonicalMapping {
public static void main(String[] args) {
int size = 100000;
// Or, choose size via the command line:
if(args.length > 0)
size = new Integer(args[0]);
Key[] keys = new Key[size];
WeakHashMap<Key,Value> map =
new WeakHashMap<Key,Value>();
for(int i = 0; i < size; i++) {
Key k = new Key(Integer.toString(i));
Value v = new Value(Integer.toString(i));
if(i % 3 == 0)
keys[i] = k; // Save as "real" references
map.put(k, v);
}
System.gc();
System.gc();
System.gc();
}
}
我的理解是,最后键值为3的倍数的键不应该被回收,但是执行结果里3的倍数却被回收了
是我的理解有误吗?麻烦大神指导一下
这是一条镜像帖。来源:北邮人论坛 / java / #48181同步于 2016/3/6
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
WeakHashMap存在强引用却被垃圾回收机制回收了
hhbb
2016/3/6镜像同步4 回复
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
java对于引用分为,强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,WeakHashMap弱引用,对象的生存只能到下一次GC前,也就是无论是否有强引用,最后一定会回收的。
多谢啊
但是好像不是这个样子吧!Java编程思想上对WeakHashMap是这么说的
“A map of weak keys that allow objects referred to by the map to be released; designed to solve certain types of problems. If no references to a particular key are held outside the map, that key may be garbage collected. ”
【 在 wbzj1110 的大作中提到: 】
: java对于引用分为,强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,WeakHashMap弱引用,对象的生存只能到下一次GC前,也就是无论是否有强引用,最后一定会回收的。
看样子优化器太聪明了,在你调用GC的时候就已经知道你的keys数组不会再用了,所以就认为keys数组死了,然后里面所有的key都没有强引用了。泡泡我这个程序试试看。然后,把最后读取keys的那个for循环注释掉试试看。
p.s. Java并不保证在程序退出的时候所有的对象的finalize方法都会被调用。所有如果不加那些System.gc(),有可能某些对象的finalize永远不会被调用。
package cn.byr.nuanyangyang.weakmap;
import java.util.WeakHashMap;
class Element {
private String ident;
private String msg;
private boolean important;
public Element(String id) {
ident = id;
int rem = Integer.parseInt(ident) % 3;
msg = String.format("Finalizing %s %s (%d)", getClass().getSimpleName(), ident, rem);
important = this instanceof Key && rem == 0;
}
public String toString() {
return ident;
}
public int hashCode() {
return ident.hashCode();
}
public boolean equals(Object r) {
return r instanceof Element && ident.equals(((Element) r).ident);
}
protected void finalize() {
if (important) {
System.out.println(msg);
}
}
}
class Key extends Element {
public Key(String id) {
super(id);
}
}
class Value extends Element {
public Value(String id) {
super(id);
}
}
public class CanonicalMapping {
public static void main(String[] args) {
int size = 100000;
// Or, choose size via the command line:
if (args.length > 0)
size = new Integer(args[0]);
Key[] keys = new Key[size];
WeakHashMap<Key, Value> map = new WeakHashMap<Key, Value>();
for (int i = 0; i < size; i++) {
Key k = new Key(Integer.toString(i));
Value v = new Value(Integer.toString(i));
if (i % 3 == 0)
keys[i] = k; // Save as "real" references
map.put(k, v);
}
System.gc();
System.gc();
System.gc();
System.out.println("----------------------------------- Start counting here.");
int nkeys = 0;
for (Key k: keys) {
nkeys++;
}
System.out.printf("----------------------------------- nkeys=%d\n", nkeys);
System.out.println("----------------------------------- Main ends here.");
System.gc();
System.gc();
System.gc();
}
}
多谢暖神指点啊!我试着把储存键值引用的数组做为类变量时,发现却不会回收键值为3的倍数的键。应该也是由于优化器的缘故。
【 在 nuanyangyang 的大作中提到: 】
: 看样子优化器太聪明了,在你调用GC的时候就已经知道你的keys数组不会再用了,所以就认为keys数组死了,然后里面所有的key都没有强引用了。泡泡我这个程序试试看。然后,把最后读取keys的那个for循环注释掉试试看。
: p.s. Java并不保证在程序退出的时候所有的对象的finalize方法都会被调用。所有如果不加那些System.gc(),有可能某些对象的finalize永远不会被调用。
: [code=java]
: ...................