目錄
文章內容
JVM記憶體模型-原理圖
程式計數器
虛擬機堆疊
方法區
java堆
直接記憶體
jdk6,7,8的記憶體模型區別
文章內容
解決一下問題:
1.JVM有哪些空間?
運行時資料區:程式計數器,虛擬機堆疊,本地方法堆疊,方法區,java堆以及直接記憶體,
2.執行緒共享還是獨享?
程式計數器,虛擬機堆疊,本地方法堆疊為執行緒獨享,
方法區,java堆為執行緒共享,
3. 有沒有可能例外?
程式計數器 這個記憶體區域是唯一一個在java虛擬機規范中沒有規定任何OutOfMemoryError的情況的區域,
4.JVM的優化?
暫時沒深入,
JVM記憶體模型-原理圖

直接呼叫本地庫: native ,
程式計數器
特征
1.因為處理器在一個確定是時刻只會執行一個執行緒中的指令,執行緒切換后,是通過計數器來記錄執行痕跡的,因此程式計數器是每個執行緒私有的,
2.如果執行的是java方法,那么記錄的是正在執行的虛擬機位元組碼指令的地址的地址,如果是native方法,計數器的值為空(undefined),
作用
程式計數器是一塊較小的記憶體空間,可以看作是當前執行緒所執行的位元組碼的行號指示器,分支、回圈、跳轉、例外處理、執行緒恢復等基礎功能都需要依賴這個計數器來完成,
例外
這個記憶體區域是唯一一個在java虛擬機規范中沒有規定任何OutOfMemoryError的情況的區域,
虛擬機堆疊
特征
執行緒私有,
后進先出(LIFO)堆疊,
存盤堆疊幀,支持Java方法的呼叫、執行和退出,
可能出現OutOfMemoryError例外和StackOverflowError例外,
作用
用于存盤區域變數表、運算元堆疊、動態鏈接、方法出口等資訊,每一個方法的執行就對應著堆疊幀在虛擬機堆疊中的入堆疊,出堆疊程序,
例外
例外:執行緒請求的堆疊幀深度大于虛擬機所允許的深度---StackOverFlowError,如果虛擬機堆疊可以動態擴展(大部分虛擬機允許動態擴展,也可以設定固定大小的虛擬機堆疊),但是無法申請到足夠的記憶體---OutOfMemorError,

方法區
作用
執行緒共享,方法區中存盤了每個型別的對應的常量池,即虛擬機加載的類資訊、常量、靜態變數、即時編譯器編譯后的代碼等等,(HotSpot虛擬機上開發部署人員更愿意成為“永久代”,Permanent Generation),
例外
方法區溢位也是一種常見的記憶體溢位例外,
特征
1.又叫靜態區,跟堆一樣,被所有的執行緒共享,方法區包含所有的class和static變數,
2.方法區中包含的都是在整個程式中永遠唯一的元素,如class,static變數,
記憶體引數配置
通過jvm引數:-XX:PermSize、-XX:MaxPermSize來設定方法區大小,
java堆
堆記憶體(垃圾收集器重點關注區)
特征
Java 中的堆是 JVM 所管理的最大的一塊記憶體空間,主要用于存放各種類的實體物件
作用
在 Java 中,堆被劃分成兩個不同的區域:新生代 ( Young )、老年代 ( Old ),新生代 ( Young ) 又被劃分兩個區域:Eden、From Survivor、To Survivor,
模型
堆大小 = 新生代 + 老年代,
新生代 ( Young ) 與老年代 ( Old ) 的默認比例的值為 1:2,其中,新生代 ( Young ) 被細分為 Eden 和 兩個 Survivor 區域,這兩個 Survivor 區域分別被命名為 from 和 to,以示區分,
所以,默認的,Eden : from : to = 8 : 1 : 1,
GC 堆
Minor GC
Minor GC 是發生在新生代中的垃圾收集動作,所采用的是復制演算法,
新生代幾乎是所有 Java 物件出生的地方,即 Java 物件申請的記憶體以及存放都是在這個地方,Java 中的大部分物件通常不需長久存活,具有朝生夕滅的性質,
當一個物件被判定為 “死亡” 的時候,GC 就有責任來回收掉這部分物件的記憶體空間,新生代是 GC 收集垃圾的頻繁區域,
當物件在 Eden ( 包括一個 Survivor 區域,這里假設是 from 區域 ) 出生后,在經過一次 Minor GC 后,如果物件還存活,并且能夠被另外一塊 Survivor 區域所容納
( 上面已經假設為 from 區域,這里應為 to 區域,即 to 區域有足夠的記憶體空間來存盤 Eden 和 from 區域中存活的物件 ),則使用復制演算法將這些仍然還存活的物件復制到另外一塊 Survivor 區域 ( 即 to 區域 ) 中,然后清理所使用過的 Eden 以及 Survivor 區域 ( 即 from 區域 ),并且將這些物件的年齡設定為1,以后物件在 Survivor 區每熬過一次 Minor GC,就將物件的年齡 + 1,當物件的年齡達到某個值時 ( 默認是 15 歲,可以通過引數 -XX:MaxTenuringThreshold 來設定 ),這些物件就會成為老年代,
但這也不是一定的,對于一些較大的物件 ( 即需要分配一塊較大的連續記憶體空間 ) 則是直接進入到老年代,
Full GC ( 或稱為 Major GC )
Full GC 是發生在老年代的垃圾收集動作,所采用的是標記-清除演算法,
現實的生活中,老年代的人通常會比新生代的人 “早死”,堆記憶體中的老年代(Old)不同于這個,老年代里面的物件幾乎個個都是在 Survivor 區域中熬過來的,它們是不會那么容易就 “死掉” 了的,因此,Full GC 發生的次數不會有 Minor GC 那么頻繁,并且做一次 Full GC 要比進行一次 Minor GC 的時間更長,
另外,標記-清除演算法收集垃圾的時候會產生許多的記憶體碎片 ( 即不連續的記憶體空間 ),此后需要為較大的物件分配記憶體空間時,若無法找到足夠的連續的記憶體空間,就會提前觸發一次 GC 的收集動作,
配置

直接記憶體
它不是jvm運行時資料區的一部分,也不是jvm規范中定義的記憶體區域,主要用于與I/O相關的一些API中,
jdk6,7,8的記憶體模型區別
jdk8取消了方法區,用元空間來代替,它在jvm記憶體空間外,由本地記憶體分配空間來保存,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296798.html
標籤:其他
