关于IntegerCache的理解

今天在javaeye上看到一兄弟贴的代码,

                1:            int a = 1000, b = 1000; 
		2: 	    System.out.println(a == b); 

		3:	    Integer c = 1000, d = 1000; 
		4:	    System.out.println(c == d); 
		5:	    Integer e = 100,h = 100; 
		6:	    System.out.println(e == h);

 运行程序后,输出的结果是:true false true, 看到这个结果,我是百思不得其解,第三行跟第五行明明初始化的一样,为什么结果不一样呢,于是找答案

    原来根据java语言规范,符合规范的Java实现必须保证Integer的缓存至少要覆盖[-128, 127]的范围。

 使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN参数即可将Integer的自动缓存区间设置为[-128,NNN]。注意区间的下界固定在-128不可配置。 

在client模式下该参数无效。这个参数是server模式专有的,在c2_globals.hpp中声明,默认值是128;不过这个默认值在默认条件下不起作用,要手动设置它的值或者是开启-XX:+AggressiveOpts参数才起作用。 
在设置了-XX:+AggressiveOpts启动参数后,AutoBoxCacheMax的默认值会被修改为20000并且生效

 

从这里,也就是说在sun jdk的server模式中可以通过设置-XX:AutoBoxCacheMax这个参数来确定Integer自动缓存的大小,然后在client模式中这个参数是不支持的,但是可以通过启用-XX:+AggressiveOpts这个参数来调整Integer的自动缓存大小,可调整到20000,请看下面JVM实现代码:

// Aggressive optimization flags  -XX:+AggressiveOpts  
void Arguments::set_aggressive_opts_flags() {  
#ifdef COMPILER2  
  if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) {  
    if (FLAG_IS_DEFAULT(EliminateAutoBox)) {  
      FLAG_SET_DEFAULT(EliminateAutoBox, true);  
    }  
    if (FLAG_IS_DEFAULT(AutoBoxCacheMax)) {  
      FLAG_SET_DEFAULT(AutoBoxCacheMax, 20000);  
    }  
  
    // Feed the cache size setting into the JDK  
    char buffer[1024];  
    sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);  
    add_property(buffer);  
  }  
  // ...  
#endif  
}  

 

然后再回到代码本身,Integer e = 100,h = 100; 这里编译器会自动帮我们进行box操作,所谓自动装箱即会调用Integer.valueOf(int)方法,

同时这个值100有事在缓存区域内,所以会直接读取缓存的内容;不过Integer c = 1000, d = 1000; 1000是大于Integer的默认缓存范围的,所以c d是不相等的。

 

同时也可以测试:Integer e = 100 ,f =  Integer.valueOf(100), 可以发现 e == f也会打印true,

但是 Integer h = 100, g = new Integer(100); g是新建了一个Integer对象, 所以h g是不相等的。

你可能感兴趣的:(Integer)