package statictest;
import java.util.*;
class A
{
int a=3;
String str="hello";
public String toString()
{
return str+String.valueOf(a);
}
}public class StaticTest
{
public static void main(String[] args) throws Exception
{
Map map=new WeakHashMap();
String a="a";
String av="av";
A ca=new A();
map.put("ca", ca);
map.put(a, av);
System.out.println(map);
System.gc();
a=null;
ca=null;
Thread.sleep(1000);
System.gc();
System.gc();
System.out.println(map);
/*运行结果:
{a=av, ca=hello3}
{a=av, ca=hello3}
两次一样*/
Map map2=new WeakHashMap();
map2.put("obj", new A());
A xyz=(A)map2.get("obj");
System.out.println(map2);
xyz.a=10000;
System.out.println(map2);
/*运行结果:
{obj=hello3}
{obj=hello10000}
对象的成员变量可改变*/
}}疑惑1:
为什么我把WeakHashMap的键设为了null,而且也调用了垃圾回收器,也让主线程休眠了一段时间,可是这个map还是不放掉这一对值?
疑惑2:
map里的值存的一律是引用,可是为什么我将第一个map的键ca对应的值设为了null,可是它打印出来还是原来的值?而第二个map2里面我更改了它里面保存对象的成员值后,能反应出正确的结果?
import java.util.*;
class A
{
int a=3;
String str="hello";
public String toString()
{
return str+String.valueOf(a);
}
}public class StaticTest
{
public static void main(String[] args) throws Exception
{
Map map=new WeakHashMap();
String a="a";
String av="av";
A ca=new A();
map.put("ca", ca);
map.put(a, av);
System.out.println(map);
System.gc();
a=null;
ca=null;
Thread.sleep(1000);
System.gc();
System.gc();
System.out.println(map);
/*运行结果:
{a=av, ca=hello3}
{a=av, ca=hello3}
两次一样*/
Map map2=new WeakHashMap();
map2.put("obj", new A());
A xyz=(A)map2.get("obj");
System.out.println(map2);
xyz.a=10000;
System.out.println(map2);
/*运行结果:
{obj=hello3}
{obj=hello10000}
对象的成员变量可改变*/
}}疑惑1:
为什么我把WeakHashMap的键设为了null,而且也调用了垃圾回收器,也让主线程休眠了一段时间,可是这个map还是不放掉这一对值?
疑惑2:
map里的值存的一律是引用,可是为什么我将第一个map的键ca对应的值设为了null,可是它打印出来还是原来的值?而第二个map2里面我更改了它里面保存对象的成员值后,能反应出正确的结果?
class Mouse
{
private int i;
Mouse(int i){
this.i=i;
}
public String toString(){return "Mouse "+i;}
}
public class Test2
{
public static void main(String[] args)
{
Map hashMap=new WeakHashMap();
Mouse s=new Mouse(1);
s=null;
hashMap.put(s,new Integer(1));
//s=null;
System.out.println(hashMap);
}
}
java Test2
打印:null=1
字符串表现出的性质让人百思不解,它虽然是最终类,可是集合里保存的是引用,不是它本身,理说这个引用会指向新对象,可是为什么还是指向老对象呢?老对象不是应该会GC回收的吗?
代码如下:
package statictest;
import java.util.*;
import java.lang.ref.*;
import java.lang.ref.*;class A
{
int a=3;
String str="hello";
public String toString()
{
return str+a;
}
}public class StaticTest
{
public static void main(String[] args) throws Exception
{
Map map=new WeakHashMap();
String b="this is b:";
A ab=new A();
map.put(ab, new A());
map.put(b, "b");
System.out.println(map);
String c=(String)map.get(b);
c=null; //把键b的值设为null,但打印出来却没有变化.
ab=null; //由于ab是一个类对象的引用,所以会被移出map
b=null; //可是键b也是一个对象,为什么置为null时会没变化呢??
System.gc(); //一定要调用,否则GC来不及回收,仍会打印出原来的键值对
System.out.println(map);
}}
打印结果:
{hello3=hello3, this is b:=b}
{this is b:=b}
再者可能也是由于gc()只回收堆区而非栈区的垃圾内存
导致了这种情况的发生。
import java.util.WeakHashMap;
class StaticTest
{
int a=3;
String str= "hello "; public String toString()
{
return str+a;
}
public static void main(String[] args) throws Exception
{
Map map=new WeakHashMap();
String b= new String("this is b: ");
StaticTest ab=new StaticTest();
map.put(ab, new StaticTest());
map.put(b, "b ");
System.out.println(map);
String c=(String)map.get(b);
c=null; //把键b的值设为null,但打印出来却没有变化.
ab=null; //由于ab是一个类对象的引用,所以会被移出map
b=null; //b在堆内存中,这下没打印出东西来了
System.gc(); //一定要调用,否则GC来不及回收,仍会打印出原来的键值对
System.out.println(map);
}
} {this is b: =b , hello 3=hello 3}
{}