請點擊上面藍橋杯 免費訂閱!
今天藍橋杯軟體學院鄭老師為大家分享Java性能優化,基本類型 vs 引用類型。希望大家能夠喜歡:
在Java性能優化系列中,內存管理是一個要優先考慮的關鍵因素。而說到內存分配,就必然會涉及到基本類型和引用類型。所以我們今天就先來介紹一下這兩種類型在性能方面各自有什麼奧妙。
★名詞定義
先明確一下什麼是基本類型,什麼是引用類型。簡單地說,所謂基本類型就是Java語言中如下的8種內置類型:boolean、char、byte、 short、int、long、float、double。而引用類型就是那些可以通過new來創建對象的類型(基本上都是派生自Object)。
★兩種類型的存儲方式
這兩種類型的差異,首先體現在存儲方式上。
◇引用類型的創建
當你在函數中創建一個引用類型的對象時,比如下面的語句:
StringBuffer str = new StringBuffer();
該StringBuffer對象的內容是存儲在堆(Heap)上的,需要申請堆內存。而變量str只不過是針對該StringBuffer對象的一個引用(或者叫地址)。變量str的值(也就是StringBuffer對象的地址)是存儲在棧上的。
◇基本類型的創建
當你在函數中創建一個基本類型的變量時,比如如下語句:
int n = 123;
這個變量n的值也是存儲在棧(Stack)上的,但是這個語句不需要再從堆中申請內存了。
★堆和棧的性能差異
可能有同學會小聲問:堆和棧有啥區別捏?要說堆和棧的差別,那可就大了去了。如果你對這兩個概念還是不太明白或者經常混淆,建議先找本作業系統的書拜讀一下。
由於本系列是介紹性能,所以來討論一下堆和棧在性能方面的差別(這個差異是很大滴)。堆相對進程來說是全局的,能夠被所有線程訪問;而棧是線程局部的,只能本線程訪問。打個比方,棧就好比個人小金庫,堆就好比國庫。你從個人小金庫拿錢去花,不需要辦什麼手續,拿了就花,但是錢數有限;而國庫裡面的錢雖然很多,但是每次申請花錢要打報告、蓋圖章、辦N多手續,耗時又費力。
同樣道理,由於堆是所有線程共有的,從堆裡面申請內存要進行相關的加鎖操作,因此申請堆內存的複雜度和時間開銷比棧要大很多;從棧裡面申請內存,雖然又簡單又快,但是棧的大小有限,分配不了太多內存。
★為什麼這樣設計?
可能有同學又問了,幹嘛把兩種類型分開存儲,幹嘛不放到一起捏?這個問題問得好!下面我們就來揣測一下,當初Java為啥設計成這樣。
當年Java它爹(James Gosling)設計語言的時候,對於這個問題有點進退兩難。如果把各種東東都放置到棧中,顯然不現實,一來棧是線程私有的(不便於共享),二來棧的大小是有限的,三來棧的結構也間接限制了它的用途。那為啥不把各種東東都放置到堆裡面捏?都放堆裡面,倒是能繞過上述問題,但是剛才也提到了,申請堆內存要辦很多手續,太繁瑣。如果僅僅在函數中寫一個簡單的「int n = 0;」,也要到堆裡面去分配內存,那性能就大大滴差了(要知道Java是1995年生出來的,那年頭我家的PC配4兆內存就屬豪華配置了)。
左思右想之後,Java它爹只好做了一個折中:把類型分為基本類型和引用類型,兩者使用不同的創建方式。這種差異從Java語法上也可以看出來:引用類型可以用new創建對象(對於某些單鍵,表面上沒用new,但是在getInstance()內部也還是用的new);而基本類型則不需要用new來創建。
★這樣設計的弊端
順便跑題一下,鬥膽評價Java它爹這種設計的弊端(希望Java Fans不要跟我急)。我個人認為:這個折中的決策,帶來了許多深遠的影響,隨手舉出幾個例子:
1、由於基本類型不是派生自Object,因此不能算是純種的對象。這導致了Java的「純面向對象」招牌打了折扣(當年Sun老是吹噓Java是純OO的語言)。
2、由於基本類型不是派生自Object,出於某些場合(比如容器類)的考慮,不得不為每個基本類型加上對應的包裝類(比如Integer、Byte等),使得語言變得有點冗餘。
★結論
從上述的介紹,我們應該明白,使用new創建對象的開銷是不小的。在程序中能避免就應該儘量避免。另外,使用new創建對象,不光是創建時開銷大,將來垃圾回收時,銷毀對象也是有開銷的.
如果大家還不明白的話,歡迎大家參加藍橋杯軟體學院的免費實訓計劃。
藍橋杯軟體學院由線下企業級軟體培訓及在線教育兩部分組成。線下,通過高校合作、共建校內實訓基地,專注培養具備網際網路思維,精通Java、ios、android等主流技術的優秀技術人才。線上,提供豐富、實用、前沿的泛IT領域培訓內容,幫助IT人士個人成長及終身學習,打造泛IT領域人士的卓越學習平臺。
藍橋杯軟體學院基地風採
想了解更多藍橋杯軟體學院信息,請點擊下方閱讀原文,即可跳轉到我們的網頁。
============================
分享最光榮!輕擊屏幕右上方即刻分享!
或微信查找"bluebridgecup」關注我們!
掃一掃下方二維碼關注我們也是極好的!