Java Integer的緩存策略

先看一段代碼:

integer1 = Integer.valueOf(4);
integer2 = 4;
System.out.println(integer1 == integer2);

integer1 = 4;
integer2 = 4;
System.out.println(integer1 == integer2);

integer1 = 129;
integer2 = 129;
System.out.println(integer1 == integer2);

輸出結(jié)果為:

true
true
false

這是為何呢钾唬?
在 Java 5 中十办,為 Integer 的操作引入了一個新的特性,用來節(jié)省內(nèi)存和提高性能嗅绰。整型對象在內(nèi)部實現(xiàn)中通過使用相同的對象引用實現(xiàn)了緩存和重用舍肠,上面的規(guī)則適用于整數(shù)區(qū)間 -128 到 +127。

這種 Integer 緩存策略僅在自動裝箱(autoboxing)的時候有用窘面,使用構(gòu)造器創(chuàng)建的 Integer 對象不能被緩存翠语。所以一下代碼輸出結(jié)果是false:

// 沒有自動裝箱
Integer integer1 = new Integer(3);
Integer integer2 = 3;   
System.out.println(integer1 == integer2);

Java 編譯器把原始類型自動轉(zhuǎn)換為封裝類的過程稱為自動裝箱(autoboxing),這相當于調(diào)用 valueOf 方法

Integer a = 10; //this is autoboxing
Integer b = Integer.valueOf(10); //under the hood

我們來看看 valueOf 的源碼:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

在創(chuàng)建新的 Integer 對象之前會先在 IntegerCache.cache 中查找财边。有一個專門的 Java 類來負責 Integer 的緩存肌括。IntegerCache 是 Integer 類中一個私有的靜態(tài)類。我們來看看這個類酣难,有比較詳細的文檔谍夭,可以提供我們很多信息。

/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 *
 * The cache is initialized on first usage.  The size of the cache
 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
 * During VM initialization, java.lang.Integer.IntegerCache.high property
 * may be set and saved in the private system properties in the
 * sun.misc.VM class.
 */

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                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);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

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

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

Javadoc 詳細的說明這個類是用來實現(xiàn)緩存支持憨募,并支持 -128 到 127 之間的自動裝箱過程慧库。最大值 127 可以通過 JVM 的啟動參數(shù) -XX:AutoBoxCacheMax=size 修改。緩存通過一個 for 循環(huán)實現(xiàn)馋嗜。從小到大的創(chuàng)建盡可能多的整數(shù)并存儲在一個名為 cache 的整數(shù)數(shù)組中齐板。這個緩存會在 Integer 類第一次被使用的時候被初始化出來。以后葛菇,就可以使用緩存中包含的實例對象甘磨,而不是創(chuàng)建一個新的實例(在自動裝箱的情況下)。

實際上在 Java 5 中引入這個特性的時候眯停,范圍是固定的 -128 至 +127济舆。后來在 Java 6 中,最大值映射到 java.lang.Integer.IntegerCache.high莺债,可以使用 JVM 的啟動參數(shù)設(shè)置最大值滋觉。這使我們可以根據(jù)應用程序的實際情況靈活地調(diào)整來提高性能。是什么原因選擇這個 -128 到 127 這個范圍呢齐邦?因為這個范圍的整數(shù)值是使用最廣泛的椎侠。 在程序中第一次使用 Integer 的時候也需要一定的額外時間來初始化這個緩存。

這種緩存行為不僅適用于Integer對象措拇。我們針對所有整數(shù)類型的類都有類似的緩存機制我纪。

  • 有 ByteCache 用于緩存 Byte 對象
  • 有 ShortCache 用于緩存 Short 對象
  • 有 LongCache 用于緩存 Long 對象
  • 有 CharacterCache 用于緩存 Character 對象

Byte,Short,Long 有固定范圍: -128 到 127浅悉。對于 Character, 范圍是 0 到 127趟据。除了 Integer 可以通過參數(shù)改變范圍外,其它的都不行术健。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汹碱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子荞估,更是在濱河造成了極大的恐慌比被,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泼舱,死亡現(xiàn)場離奇詭異,居然都是意外死亡枷莉,警方通過查閱死者的電腦和手機娇昙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笤妙,“玉大人冒掌,你說我怎么就攤上這事《着蹋” “怎么了股毫?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長召衔。 經(jīng)常有香客問我铃诬,道長,這世上最難降的妖魔是什么苍凛? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任趣席,我火速辦了婚禮,結(jié)果婚禮上醇蝴,老公的妹妹穿的比我還像新娘宣肚。我一直安慰自己,他們只是感情好悠栓,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布霉涨。 她就那樣靜靜地躺著,像睡著了一般惭适。 火紅的嫁衣襯著肌膚如雪笙瑟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天癞志,我揣著相機與錄音逮走,去河邊找鬼。 笑死,一個胖子當著我的面吹牛师溅,可吹牛的內(nèi)容都是我干的茅信。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼墓臭,長吁一口氣:“原來是場噩夢啊……” “哼蘸鲸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起窿锉,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酌摇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嗡载,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窑多,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年洼滚,在試婚紗的時候發(fā)現(xiàn)自己被綠了埂息。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡遥巴,死狀恐怖千康,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铲掐,我是刑警寧澤拾弃,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站摆霉,受9級特大地震影響豪椿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜携栋,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一砂碉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刻两,春花似錦增蹭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至户誓,卻和暖如春饼灿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背帝美。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工碍彭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓庇忌,卻偏偏與公主長得像舞箍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子皆疹,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法疏橄,類相關(guān)的語法,內(nèi)部類的語法略就,繼承相關(guān)的語法捎迫,異常的語法,線程的語...
    子非魚_t_閱讀 31,643評論 18 399
  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,529評論 3 93
  • 以下內(nèi)容為作者辛苦原創(chuàng)表牢,版權(quán)歸作者所有窄绒,如轉(zhuǎn)載演繹請在“光變”微信公眾號留言申請,轉(zhuǎn)載文章請在開始處顯著標明出處崔兴。...
    光變閱讀 1,724評論 3 6
  • 上午彰导,重慶師范大學博導,國家課標組核心成員黃翔教授為我們上了核心素養(yǎng)與課程改革的深化這一講座恼布,黃教授首先...
    淺笑昨天閱讀 219評論 0 1
  • 我愛你 我是個怪物 但我愛你 余生很長,你聽我講
    太宰不治閱讀 169評論 6 1