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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章