1. 程式人生 > >Integer和int的比較,大資料量情況下造成頻繁gc的原因分析

Integer和int的比較,大資料量情況下造成頻繁gc的原因分析

很多基礎的知識,覺得沒用,所以沒有在意。當實際用到的時候,出現了不同於預想的結果,才會認真分析。

 這是shell排序的程式碼

 public long sort(Integer[] datas) {
long start = System.currentTimeMillis();

int tmp = 0;
for (int inc = datas.length/2; inc > 0; inc /=2 ) {
    for (int i=inc; i<datas.length; i++) {
        for (int j=i; j>=inc; j-=inc) {
            if (datas[j] < datas[j-inc]) {
                tmp = datas[j];
                datas[j] = datas[j-inc];
                datas[j-inc] = tmp;//這一行有問題。
            } else {
                break;
            }
        }
    }
}
long end = System.currentTimeMillis();
return (end - start);

}
datas.length = 10,000,000 。咋看一下,沒有問題,空間複雜度為datas.length+1。但是,實際執行過程中,會頻發的gc,full gc。從表面看找不原因,一點點的排除分析,最終鎖定在有註釋的的這一行。datas[j-inc]為Integer,而tmp為int,賦值的時候,將tmp自動封裝(建立)為一個Integer物件,並將引用賦值給datas[j-inc]。所以,每次執行datas[j-inc] = tmp;都會建立一個Integer物件。該程式中,這行程式碼執行的次數是O(nlogn),大概1千萬*24*20=48億位元組。所以反覆的gc,full gc是可以理解的。

 解決方法:將int tmp = 0;改為Integer tmp = 0;就可以了。

這裡引申出另一個問題,int和Integer是不同的。
for (int i=0; i<1000; i++) {
Integer m = i;
Integer n = i;
if (m != n) {
System.out.println(i);
break;
}
}
結果:128。

以前無意中看過原因,0-127因為使用頻繁,所以java預設是快取起來的,任何Integer物件的值在這個範圍內都是同一個物件。超過127,就不再相等了。

int m= 10000;
Integer n = 10000;
m == n : true,恆等。是int的比較,而不是Integer。