天天看點

jvm的記憶體如何配置設定使用?

jvm記憶體的劃分:    

未初始化
初始化
正文段

粗略的說,jvm記憶體大緻分兩塊:堆heap和非堆permanent;

從英文翻譯上看,非堆permanent是“持久”的意思,它應該是存儲需要持久存在的資料,而堆heap相對的就是不持久的資料區;

但我怎麼感覺堆heap才是持久的資料區呢?你看非堆permanent中的“棧”跟“客棧”一個字,客棧明顯住不長久,還怎麼持久???????

具體如何:

堆heap: 存儲所有的類執行個體,為數組記憶體配置設定空間;堆分為:young generation 和 old generation;

           young generation: 1*(eden sapce) + 2*(Surviver space)(from、to)

                                            Eden:伊甸園     ------- 存放新生的對象(new 對象)

                                            Surviver:存活者  ------- 經曆過垃圾回收後存活下來的對象

           old generation: 存放生命周期長的對象;

非堆permanent:  存儲java的類資訊,包括解析後得到的方法、屬性、字段等;不參與垃圾回收;

JVM記憶體申請過程如下:

  1. JVM 會試圖為相關Java對象在Eden中初始化一塊記憶體區域
  2. 當Eden空間足夠時,記憶體申請結束;否則到下一步
  3. JVM 試圖釋放在Eden中所有不活躍的對象(這屬于1或更進階的垃圾回收),釋放後若Eden空間仍然不足以放入新對象,則試圖将部分Eden中活躍對象放入Survivor區
  4. Survivor區被用來作為Eden的old的中間交換區域,當old區空間足夠時,Survivor區的對象會被移到old區,否則會被保留在Survivor區
  5. 當old區空間不夠時,JVM 會在old區進行完全的垃圾收集(0級)
  6. 完全垃圾收集後,若Survivor及old區仍然無法存放從Eden複制過來的部分對象,導緻JVM無法在Eden區為新對象建立記憶體區域,則出現”out of memory”錯誤

1、堆是在程式運作時,而不是在程式編譯時,申請某個大小的記憶體空間。即動态配置設定記憶體,對其通路和一般記憶體的通路沒有差別。

2、堆是應用程式在運作的時候請求作業系統配置設定給自己記憶體,一般是申請/給予的過程。

3、堆是指程式運作時申請的動态記憶體,而棧隻是指一種使用堆的方法(即先進後出)。

關于棧:

Java棧是與每一個線程關聯的,JVM在建立每一個線程的時候,會配置設定一定的棧空間給線程。它主要用來存儲線程執行過程中的局部變量,方法的傳回值,以及方法調用上下文。棧空間随着線程的終止而釋放。

Java堆是被所有線程共享的;

現在看來,我感覺jvm的分類應該再擴充下,分:堆、非堆、棧,我把java代碼需要加載的東西分為:類源碼、類對象(new)、類源碼方法、類源碼變量、對象方法、對象變量、參數;

類源碼----------------------->非堆

源碼方法----------------------->非堆

源碼變量----------------------->非堆

類對象--------------------------->堆

對象方法--------------------------->堆

對象變量--------------------------->堆

參數---------------------------------->棧

全局變量(成員變量)是在建立對象的時候配置設定記憶體;      

點評:其實類源碼包括了源碼方法、源碼變量,類對象包括了對象方法、對象變量;這樣再分出來的确多此一舉。但這是為了自己更好一一對照、強調,純屬個人習慣... ...

java中的類大緻分為三種(這是摘錄别人的):

    1.系統類 

    2.擴充類 

    3.由程式員自定義的類