Java5爲Integer的操做引入了一個新的特性,用來節省內存和提升性能。整型對象在內部實現中經過使用相同的對象引用實現了緩存和重用。
上面的規則默認適用於整數區間 -128 到 +127(這個整數區間能夠經過啓動應用的虛擬機參數修改:-XX:AutoBoxCacheMax)。這種Integer緩存策略僅在自動裝箱(autoboxing)的時候有用,使用構造器建立的Integer對象不能被緩存。Java 編譯器把原始類型自動轉換爲封裝類的過程稱爲自動裝箱(autoboxing),這至關於調用 valueOf 方法。java
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
首先看代碼:數組
public class TestInteger { 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); System.out.println(i == i3); System.out.println("**************"); Integer i5 = 127;//java在編譯的時候,被翻譯成-> Integer i5 = Integer.valueOf(127); Integer i6 = 127; System.out.println(i5 == i6);//true Integer i9 = 128; Integer i10 = 128; System.out.println(i9 == i10);//false Integer ii5 = new Integer(127); System.out.println(i5 == ii5); //false Integer i7 = new Integer(128); Integer i8 = new Integer(123); System.out.println(i7 == i8); //false } }
首先,7行和8行輸出結果都爲true,由於Integer和int比都會自動拆箱(jdk1.5以上)。
12行的結果爲true,而15行則爲false。java在編譯Integer i5 = 127的時候,被翻譯成-> Integer i5 = Integer.valueOf(127);因此關鍵就是看valueOf()函數了。只要看看valueOf()函數的源碼就會明白了。JDK源碼的 valueOf函數式這樣的:緩存
public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
看一下源碼你們都會明白,對於-128到127之間的數,會進行緩存,Integer i5 = 127時,會將127進行緩存,下次再寫Integer i6 = 127時,就會直接從緩存中取,就不會new了。因此12行的結果爲true,而15行爲false。
對於17行和20行,由於對象不同,因此爲false。
對於以上的狀況總結以下:函數
// IntegerCache,Integer類的內部類,注意它的屬性都是定義爲static final private static class IntegerCache { //緩存的下界,-128,不可變 static final int low = -128; //緩存上界,暫爲null static final int high; //緩存的整型數組 static final Integer cache[]; static { // 緩存上界,能夠經過JVM參數來配置 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); //最大的數組值是Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low)); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for (int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() { } }
-XX:AutoBoxCacheMax這個參數是設置Integer緩存上限的參數,在VM初始化期間java.lang.Integer.IntegerCache.high屬性能夠被設置和保存在私有的系統屬性sun.misc.VM class中。理論上講,當系統須要頻繁使用Integer時,或者說堆內存中存在大量的Integer對象時,能夠考慮提升Integer緩存上限,避免JVM重複創造對象,提升內存的使用率,減小GC的頻率,從而提升系統的性能。
理論歸理論,這個參數可否提升系統系統關鍵仍是要看堆中Integer對象到底有多少、以及Integer的建立的方式。若是堆中的Integer對象不多,從新設置這個參數並不會提升系統的性能。即便堆中存在大量的Integer對象,也要看Integer對象時如何產生的。性能
Integer的緩存上限能夠經過Java虛擬機參數修改,Byte、Short、Long、Character的緩存則無法修改。翻譯
Bytecode
private static class ByteCache { private ByteCache(){} static final Byte cache[] = new Byte[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Byte((byte)(i - 128)); } } public static Byte valueOf(byte b) { final int offset = 128; return ByteCache.cache[(int)b + offset]; }
Short對象
private static class ShortCache { private ShortCache(){} static final Short cache[] = new Short[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Short((short)(i - 128)); } } public static Short valueOf(short s) { final int offset = 128; int sAsInt = s; if (sAsInt >= -128 && sAsInt <= 127) { // must cache return ShortCache.cache[sAsInt + offset]; } return new Short(s); }
Long內存
private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } } public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); }
Characterget
private static class CharacterCache { private CharacterCache(){} static final Character cache[] = new Character[127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Character((char)i); } } public static Character valueOf(char c) { if (c <= 127) { // must cache return CharacterCache.cache[(int)c]; } return new Character(c); }
示例:
public class AllCacheDemo { /** * 演示JDK內部緩存 */ public static void main(String[] args) { Integer a = 28; Integer b = 28; println(a == b); Byte c = 25; Byte d = 25; println(c==d); Short p=12; Short q=12; println(p==q); Long x=127L; Long y=127L; println(x==y); Character m='M'; Character n='M'; println(m==n); } public static void println(Object o){ System.out.println(o); } }
做者:劉曉;花名:愚谷。
點擊 閱讀更多 查看更多詳情