Integer自動緩存池大小

之前一直看資料有寫,當一個int類型的數據<128時,用==比較是相等的,但是當>128時,比較就不相等了。

<span style="font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:KaiTi_GB2312;">public class Test {

	public static void main(String[]args ){  
        int i = 128;
        Integer i2 = 128;
        Integer i3 = new Integer(128);
        //Integer會自動拆箱爲int,所以爲true
        System.out.println(i == i2);//true
        System.out.println(i == i3);//true  
        System.out.println(i2 == i3);//false  堆對象和棧對象,對象之間比較,而自動拆箱後對象都轉換爲int比較值
        System.out.println("----------------------");
        Integer i5 = 127;//java在編譯的時候,被翻譯成-> Integer i5 = Integer.valueOf(127);
        Integer i6 = 127;
        System.out.println(i5 == i6);//true
//        Integer i51 = 128;
//        Integer i61 = 128;
//        System.out.println(i51 == i61);//false 
        Integer i52=new Integer(126);
        Integer i62=new Integer(126);
        System.out.println(i52==i62);//false  堆中兩個不同對象
        System.out.println("----------------------");
        Integer ii5 = new Integer(127);
        System.out.println(i5 == ii5); //false  堆對象和棧對象,對象之間比較,
        Integer i7 = new Integer(128);
        Integer i8 = new Integer(128);
        System.out.println(i7 == i8);  //false  <span style="line-height: 21.6px; font-family: tahoma, arial, sans-serif;">堆中兩個不同對象</span>

    
	}

}</span></span></span>

上面是一個例子,大家可以自己運行一下。之前一直不理解爲什麼?今天看了源碼才清楚。

下面把源碼貼出來,大家感受一下,@@@@@

<span style="font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:14px;">private static class IntegerCache {
       //這是默認的最小值,這個不可以改變
       static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // 源碼中寫這個是一個可以手動設置的值,但是默認是127
            int h = 127;
//通過屬性取值
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }</span></span></span>

   我們可以看到,integer的自動緩存池的大小是 [-128   127] 這也是爲什麼就我們的環境運行出來,大於127就不再相等。

通過屬性去取的high的值,sun.misc.VM.getSavedProperty,

這個屬性是在使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN參數即可將Integer的自動緩存區間設置爲[-128,NNN]。注意區間的下界固定在-128不可配置。 
在client模式下該參數無效。這個參數是server模式專有的,在c2_globals.hpp中聲明,默認值是128;不過這個默認值在默認條件下不起作用,要手動設置它的值或者是開啓-XX:+AggressiveOpts參數才起作用。 


那麼在這裏緩存池到底起到什麼作用?

Integer i5 = 127時,會將127進行緩存,下次再寫Integer i6 = 127時,就會直接從緩存中取,就不會new了。所以22行的結果爲true,而25行爲false。(自動裝箱時纔會發生,Integer a=value,這種棧對象形式(類似 string str="abc"),如果Integer b= new Integer(value),則不會,分別在堆中建立對象)

 

對於23行和26行,因爲對象不一樣,所以爲false。

 

對於以上的情況總結如下:

 

  ①無論如何,Integer與new Integer不會相等(棧對象,堆對象)。不會經歷拆箱過程,i3的引用指向堆,而i4指向專門存放他的內存(常量池),他們的內存地址不一樣,所以爲false。

  ②兩個都是非new出來的Integer(兩個棧對象,涉及自動裝箱),如果數在-128到127之間,則是true,否則爲false

  java在編譯Integer i2 = 128的時候,被翻譯成-> Integer i2 = Integer.valueOf(128);而valueOf()函數會對-128到127之間的數進行緩存。

  ③兩個都是new出來的,都爲false(兩個堆對象)。

  ④int和integer(無論new否)比(Integer涉及自動拆箱),都爲true,因爲會把Integer自動拆箱爲int再去比。



發佈了43 篇原創文章 · 獲贊 15 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章