Java WeakHashMap 分析

昨天在我们的系统中看到了这样的一行代码:
private final Map<String, String> CACHE = new WeakHashMap();


对于
WeakHashMap
而言,之前还真的没有听过, 惭愧啊!晚上就好好的研究了下,这个不对不说说强引用、软引用、弱引用、虚引用以及垃圾回收了。

1. 强引用、软引用、弱引用、虚引用

1)强引用:就是我们平时写的new了,如Object o = new Object(),这里有两点请注意,一个是o,另一个是Object。这里假设这行代码是在方法体里写的(局部和全局是有相当大的区别的),那么o就是存储在栈空间里,而Object对象是存储在堆空间里,o就是Object对象的引用了。如果o的生命周期一直存在,那么Object对象是一直不会被回收的,即使空间不足了,它也不会回收,宁愿抛出 OutOfMemery的异常。现在是写在方法体里了,当调用这个方法结束时,o的生命周期就结束了,此时Ojbect对象就没有引用了,垃圾回收器就会将它进行回收,具体在什么时候回收,我们就不得而知了。

2)软引用:它的特征是空间足够,不会回收,空间不足够,就会回收。垃圾回收器在回收之前做了一个操作,就是将其引用置为null了。

3)弱引用:它的特征是不管空间是否足够,它都有可能被会垃圾回收器回收。

4)虚引用:它本质是在垃圾回收后进行一定的辅助操作,它不涉及对象的生命周期。

2.WeakHashMap
  WeakHashMap,从字面上看,就知道,它是一个弱引用,它其实也是一个Map,不过它有一个特征就是:当key的对象 不可用时,它的key-value就会被回收。这里的不可用,是什么意思呢?就是这个key的对象是非强引用时,它就会变成不可用。下面会给出相应的例子来讲解。

public static void main(String args[]) throws ClassNotFoundException, SQLException, InterruptedException {
		Map<String, String> cache = new WeakHashMap();
		String key=null;
		try(Connection connection = DBConnection.getConnection()){
        		try (PreparedStatement pstmt = connection
    					.prepareStatement("SELECT F01,F02 FROM Table LIMIT 1")) {
        			try (ResultSet resultSet = pstmt.executeQuery()) {
    					if (resultSet.next()) {
    						System.out.println("F01 = " +resultSet.getString(1));
    					//	key=resultSet.getString(1);    // --(1)
    					//	cache.put(key, resultSet.getString(2));  // --(2)
    						cache.put(resultSet.getString(1),resultSet.getString(2));   // --(3)
    					}
    				}
        		}	
          }
		
		while(true){
			System.gc();
			Thread.sleep(50000);
			System.out.println("get value:"+cache.get("BAOFUPAY.BF_CHARGE_PAGEURL"));
			
		}
	}


请注意:

1)如果将 1),2)注释掉,则输出的结果为null;
2)如果将3)注释掉,1) 2) 打开则输出的结果为key的value值。


怎么是这样的呢?这是因为
resultSet.getString(1)
,它是匿名对象,是没有引用的,这个key很快就会变成不可用,如果有一个key的变量,如上面所写,
key=resultSet.getString(1)
,它就变成了一个强引用了,此时就不可能被回收了。

猜你喜欢

转载自gaofulai1988.iteye.com/blog/2259290