jvm虛擬機器載入類,是把類的屬性和方法全載入了嗎

HD243608836發表於2018-05-05

問題:

比如我一個程式裡有30個類
1程式執行時候,虛擬機器是一下把30類都載入還是用哪個類載入哪個類?
2類裡有屬性和方法,那載入某個類的時候,是把該類裡的所有屬性和方法都載入,還是根據我呼叫該類的哪個方法就載入哪個方法,,其它沒用到的方法並不載入?
下面這倆句話
懶漢式是,只有用到這個用例的時候,再將他例項化,不會浪費,所以效率要高一些。
餓漢式則是程式只要開始,就將他例項化,到用到他的時候就省去了再例項的時間,所以速度和反應快。

什麼叫程式開始?難道說程式一執行就把所有類都載入了嗎?不是說用到那個類才載入哪個類嗎?請解釋下咋回事

解答:

我來回答一下你的問題:
1、類的載入時機:當這個類被例項化的時候如:new A();或者執行這個類裡面的static(靜態方法時)如:main方法,這個類才會被載入。你說的30個類它不會一下被載入,只有出現以上2種情況的時候才會載入。當然java.lang這個包裡的類會在java虛擬機器啟動的時候載入(載入是將編譯後的.class檔案載入)。
2、類裡面的屬性分為靜態的屬性,和非靜態的屬性。
2.1 靜態的屬性只會載入一次,第一次例項化的時候分配空間,以後再例項化這個類的時候不會再分配記憶體空間。這個靜態屬性屬於這個類的,供這個類的所有例項共享。
2.2非靜態的屬性會在每次例項化的時候就會分配記憶體空間,假如一個類被例項化10次,那麼這個屬性會分配10次記憶體空間,並且它只屬於當前自己例項,不屬於其他的例項物件。
2.3至於方法就是方法被呼叫的時候才會執行,你說的載入其實在例項化這個類的時候這個方法就被以.class檔案載入到虛擬機器裡了。
3、程式的開始一般是以main方法開始執行的時候就叫程式的開始。
希望我的回答對你有幫助。^_^
追問
那是不是說例項化的時候,這個類的屬性和方法都會載入到記憶體?
比如我只new A了但是我沒呼叫任何屬性和方法,那請問這個類裡面的屬性和方法是否已經全被載入到記憶體裡了?即使我沒有呼叫這個類裡面的屬性和方法,但是我只例項化了而已
追答
在你例項化的時候就已經載入到記憶體裡,並給你的屬性分配空間,分配大小按照屬性型別來分,這個和你調不呼叫沒有關係,這個java機制就是這樣的。
在你例項化的時候就已經載入到記憶體裡,並給你的屬性分配空間,分配大小按照屬性型別來分,這個和你調不呼叫沒有關係,這個java機制就是這樣的。
追問
原來如此,對了,那在請教下,懶漢和餓漢,如果不考慮執行緒安全的情況下,這倆有什麼區別?因為我知道一個是類載入時候例項化,一個是呼叫方法裡例項化,但是最後都是例項化了,我感覺不到區別?這個怎麼破。。
追答
懶漢式載入是以犧牲時間換取記憶體空間(減少記憶體空間的佔用),餓漢式是以犧牲記憶體空間來換取時間(節約時間),程式設計中時間和空間是不可能兼得的,只能在他們中間平衡選取。
追問
你說的是多個單例的時候存在這種情況,如果我說如果就只有一個單例,懶漢和餓漢就不存在這種情況吧?因為如果只有一個單例,載入時候例項和呼叫方法時候例項感覺不出太大的區別。
只是載入的時機不同而已,但是結果都是建立出例項物件。
追答
如果是單例的情況,他們主要區別有:
1、餓漢式載入是第一次例項化得時候就會建立一個static的例項,執行緒安全,但有可能造成記憶體的浪費。
2、懶漢式載入會在需要用到這個例項的時候才例項化,如果是單例一般會加一個if語句判斷是否為空if(a = =null)再建立例項,這時候就會出現執行緒不安全的情況。所以為防止執行緒不安全會加鎖,但是這樣會造成程式執行的效率下降。
一般推薦餓漢式載入的方式。
追問
那都判斷a==null 還要加鎖嗎?如果不為空 就返回例項物件就行了  既然判斷了 還會出現執行緒不安全嗎?
追答
是的要加鎖,因為如果多個執行緒同時進入時(在物件還沒有建立完成),就會同時出現這幾個執行緒同時判別為空,就會每個執行緒都建立例項a,所以出現執行緒不安全。

轉載自:https://zhidao.baidu.com/question/744005234279043572.html

相關文章