[Java] int 與 Integer 的差別

最近被問到這個問題,當下我有點愣住,其實之前我沒有深思過這個問題,那時我只知道 int 是原生資料型態、Integer 是類別資料型態,以及他們的型態之間的差異,其他細節我不是很清楚。但我隱約感覺他想問的不只是這些,果不其然他接著問在記憶體方面他們有什麼差別呢?其實關於這點,我並不是很清楚,我只知道 int 是 32 bits (4 bytes),這點在很多介紹 Java 的書或是教學裡都會提到,通常不會不知道這個。但 Integer 呢?他在記憶體裡佔多少空間呢?一樣是 4 bytes 嗎?

為了解答這個問題,後來我 google “java int integer difference",找到了這篇文章。Difference between an Integer and int in Java。文章裡面條列出一些差別,其中也包含記憶體配置。int 如我們所知,在記憶體裡佔了 4 bytes;而 Integer 則是 16 bytes

為了深入了解是什麼造成他們的差異,我接著 google “java object size",找到了這篇文章。Java Tip 130: Do you know your data size? 雖然文章年代有點久遠,但我覺得裡面的知識還是值得參考,而且他有附程式碼,照著做我們也可以獲得一些新數據。文章裡的概念是這樣,在程式碼裡 new 一些物件,然後在之前與之後分別量測記憶體使用量,他們之間的差值就是配置給這些物件的記憶體量,然後再除以物件個數,我們就可以得出單個物件的記憶體量。照著這個範例做,我們可以看到,Object 這個類別他自己本身就佔了 16 bytes。

關於 object header,有興趣的人可以 google “java object header",就會找到很多相關資訊。這裡我們就不深入研究 object header 的細節,畢竟這是另一個主題,聊下去會離題太遠。

回到記憶體這個話題上。事實上 object header 本身只佔 12 bytes(1),但因為 JVM 會將物件大小對齊 8 的倍數,所以一個 object 就會用掉 16 bytes。但如果我們的 object 是 Integer 的話,他一樣會是 16 bytes,因為 12 + 4 = 16,而 16 剛好已經是 8 的倍數,所以 JVM 就不會做對齊。

現在,讓我們回到最原始的題目,int 跟 Integer 在記憶體用量上有什麼差別?
答案是,int 佔 4 types,Integer 佔 16 bytes。

(1) 在某種情況下會是 16 bytes。這一樣是 object header 相關的主題,有興趣的人可以看看這篇 Java object header,他裡面有提到 pointer compression 並解釋什麼情況下會是 16 bytes、什麼情況下是 12 bytes。

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料