JVM學習筆記-01
JVM學習筆記
一、JVM記憶體模型
1.Java堆(Heap)
是Java虛擬機器所管理的記憶體中最大的一塊。Java堆是被所有執行緒共享的一塊記憶體區域,在虛擬機器啟動時建立。此記憶體區域的唯一目的就是存放物件例項,幾乎所有的物件例項都在這裡分配記憶體。
2.方法區(Method Area)
方法區(Method Area)與Java堆一樣,是各個執行緒共享的記憶體區域,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。
3.程式計數器(Program Counter Register)
程式計數器(Program Counter Register)是一塊較小的記憶體空間,它的作用可以看做是當前執行緒所執行的位元組碼的行號指示器。
4.虛擬機器棧(JVM Stacks)
與程式計數器一樣,Java虛擬機器棧(Java Virtual Machine Stacks)也是執行緒私有的,它的生命週期與執行緒相同。虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法被執行的時候都會同時建立一個棧幀(Stack Frame)用於儲存區域性變數表、運算元棧、動態連線、 方法返回地址。每一個方法被呼叫直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。
5.本地方法棧(Native Method Stacks)
本地方法棧(Native Method Stacks)與虛擬機器棧所發揮的作用是非常相似的,其區別不過是虛擬機器棧為虛擬機器執行Java方法(也就是位元組碼)服務,而本地方法棧則是為虛擬機器使用到的Native方法服務。
二、 JVM的生命週期
1.啟動:
啟動一個Java程式時,一個JVM例項就產生了,任何一個擁有public static voidmain(String[] args)函式的class都可以作為JVM例項執行的起點。
2.執行:
main()作為該程式初始執行緒的起點,任何其他執行緒均由該執行緒啟動。JVM內部有兩種執行緒:守護執行緒和非守護執行緒,main()屬於非守護執行緒,守護執行緒通常由JVM自己使用,java程式也可以表明自己建立的執行緒是守護執行緒。
3消亡:
當程式中的所有非守護執行緒都終止時,JVM才退出;若安全管理器允許,程式也可以使用Runtime類或者System.exit()來退出。
三、JVM記憶體
Java把記憶體分兩種:棧記憶體和堆記憶體。簡單來講,堆記憶體用於存放有new建立的物件和陣列,在堆中分配的記憶體,有java虛擬機器自動垃圾回收器來管理。而棧記憶體由使用的人向系統申請,申請人進行管理。
JVM堆記憶體
年輕代(YoungGen)、老年代(OldGen)
年輕代兩部分:
Eden(生成區)、Survivor(倖存區)
Survivor兩部分:FromSpace、ToSpace
Eden區佔大容量,
Eden:From Survivor:To Survivor預設比例8:1:1。
JVM非堆記憶體(方法區)
jdk8之前,存在著永久代/持久代(PermGen)
jdk8,永久代被元空間(meatspace)取代。但是元空間並不在虛擬機器中,而是使用本地記憶體。因此,預設情況下,元空間的大小僅受本地記憶體限制。
為什麼用元空間取代永久代?
字串存在永久代中,容易出現效能問題和記憶體溢位
為融合HotSpot JVM與JRockit JVM(新JVM技術)而做出的改變
記憶體申請過程:
VM會試圖為相關Java物件在年輕代的Eden區中初始化一塊記憶體區域。
當Eden區空間足夠時,記憶體申請結束。否則執行下一步。
JVM試圖釋放在Eden區中所有不活躍的物件(Young GC)。釋放後若Eden空間仍然不足以放入新物件,JVM則試圖將部分Eden區中活躍物件放入Survivor區。
Survivor區被用來作為Eden區及年老代的中間交換區域。當年老代空間足夠時,Survivor區中存活了一定次數的物件會被移到年老代。
當年老代空間不夠時,JVM會在年老代進行完全的垃圾回收(Full GC)。
Full GC後,若Survivor區及年老代仍然無法存放從Eden區複製過來的物件,則會導致JVM無法在Eden區為新生成的物件申請記憶體,即出現“Out of Memory”。
四、Java中的四種引用型別級別
物件的引用四種級別由高到低:強引用、軟引用、弱引用、虛引用
1.強引用
我們寫程式碼使用的物件就是強引用,它有其他物件或方法、變數等等指向它的引用
如果一個物件被擁有強引用,那麼垃圾回收器絕不會回收它。當記憶體空間不足,Java 虛擬機器寧願丟擲 OutOfMemoryError 錯誤,使程式異常終止,也不會靠隨意回收具有強引用的物件來解決記憶體不足問題。
2.軟引用
如果一個物件只具有軟引用,那麼如果記憶體空間足夠,垃圾回收器就不會回收它,如果記憶體空間不足了,就會回收這些物件的記憶體。只要垃圾回收器沒有回收它,該物件就可以被程式使用。軟引用可用來實現記憶體敏感的快取記憶體。
軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被垃圾回收,Java 虛擬機器就會把這個軟引用加入到與之關聯的引用佇列中。
3.弱引用
如果一個物件只具有弱引用,那該類就是可有可無的物件,因為只要該物件被 gc 掃描到了隨時都會把它幹掉。弱引用與軟引用的區別在於:只具有弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。不過,由於垃圾回收器是一個優先順序很低的執行緒, 因此不一定會很快發現那些只具有弱引用的物件。
弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被垃圾回收,Java 虛擬機器就會把這個弱引用加入到與之關聯的引用佇列中。
如果一個物件只具有弱引用,那該類就是可有可無的物件,因為只要該物件被 gc 掃描到了隨時都會把它幹掉。弱引用與軟引用的區別在於:只具有弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。不過,由於垃圾回收器是一個優先順序很低的執行緒, 因此不一定會很快發現那些只具有弱引用的物件。
4.虛引用
"虛引用"顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定物件的生命週期。如果一個物件僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收。虛引用主要用來跟蹤物件被垃圾回收的活動。
虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列(ReferenceQueue)聯合使用。當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之關聯的引用佇列中。程式可以通過判斷引用佇列中是否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。程式如果發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。
常用引數
-verbose:class
輸出jvm載入類的相關資訊,當jvm報告說找不到類或者類衝突時可此進行診斷。
-verbose:gc
輸出每次GC的相關情況。
-verbose:jni
輸出native方法呼叫的相關情況,一般用於診斷jni呼叫錯誤資訊。
-Xms512m
設定JVM初始記憶體為512m。此值可以設定與-Xmx相同,以避免每次垃圾回收完成後JVM重新分配記憶體。
-Xmx512m
設定JVM最大可用記憶體為512M。
-Xmn200m
設定年輕代大小為200M。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。持久代一般固定大小為64m,所以增大年輕代後,將會減小年老代大小。此值對系統效能影響較大,Sun官方推薦配置為整個堆的3/8。
-Xss128k
設定每個執行緒的堆疊大小。JDK5.0以後每個執行緒堆疊大小為1M,以前每個執行緒堆疊大小為256K。更具應用的執行緒所需記憶體大小進行調整。在相同實體記憶體下,減小這個值能生成更多的執行緒。但是作業系統對一個程式內的執行緒數還是有限制的,不能無限生成,經驗值在3000~5000左右。
-Xloggc:file
與-verbose:gc功能類似,只是將每次GC事件的相關情況記錄到一個檔案中,檔案的位置最好在本地,以避免網路的潛在問題。
若與verbose命令同時出現在命令列中,則以-Xloggc為準。
-Xprof
跟蹤正執行的程式,並將跟蹤資料在標準輸出輸出;適合於開發環境除錯。
效能調優引數列表:
引數及其預設值
描述
-XX:LargePageSizeInBytes=4m
設定用於Java堆的大頁面尺寸
-XX:MaxHeapFreeRatio=70
GC後java堆中空閒量佔的最大比例
-XX:MaxNewSize=size
新生成物件能佔用記憶體的最大值
-XX:MaxPermSize=64m
老生代物件能佔用記憶體的最大值
-XX:MinHeapFreeRatio=40
GC後java堆中空閒量佔的最小比例
-XX:NewRatio=2
新生代記憶體容量與老生代記憶體容量的比例
-XX:NewSize=2.125m
新生代物件生成時佔用記憶體的預設值
-XX:ReservedCodeCacheSize=32m
保留程式碼佔用的記憶體容量
-XX:ThreadStackSize=512
設定執行緒棧大小,若為0則使用系統預設值
-XX:+UseLargePages
使用大頁面記憶體
相關文章
- JVM學習筆記JVM筆記
- 學習筆記01筆記
- JVM學習筆記——初識JVMJVM筆記
- JVM核心學習筆記JVM筆記
- JVM 學習筆記(五)JVM筆記
- 今日學習JVM筆記JVM筆記
- Nodejs學習筆記-01 eventsNodeJS筆記
- JVM學習筆記之棧區JVM筆記
- 01_Linux學習筆記(一)Linux筆記
- 學習筆記-DAY01-VUE筆記Vue
- RAC學習筆記-Day_01筆記
- Gin學習筆記01 框架使用筆記框架
- G01學習筆記-8筆記
- G01學習筆記-6筆記
- G01學習筆記-2筆記
- G01學習筆記-3筆記
- G01學習筆記-7筆記
- G01學習筆記-4筆記
- G01學習筆記-1筆記
- G01學習筆記-5筆記
- JavaWeb學習筆記~01.ServletJavaWeb筆記Servlet
- JVM學習筆記(3)---OutOfMemory詳解JVM筆記
- 初級英語學習筆記01筆記
- Spring AOP學習筆記01:AOP概述Spring筆記
- 20.10.29【EndNote學習彙總筆記01】筆記
- Task01&Task02學習筆記筆記
- Redis學習筆記【01】 - 安裝RedisRedis筆記
- Java學習筆記01 - JavaSE基礎Java筆記
- JVM學習筆記——自動記憶體管理JVM筆記記憶體
- JVM學習筆記---伺服器,JVM效能監控工具JVM筆記伺服器
- JVM學習筆記——節碼執行引擎JVM筆記
- java學習筆記-4 JVM垃圾回收(GC)Java筆記JVMGC
- jvm學習筆記6:類載入器JVM筆記
- JVM學習筆記——類載入機制JVM筆記
- JVM學習筆記(4)---垃圾收集器JVM筆記
- JVM狂神說視訊學習筆記JVM筆記
- 01-Excel基礎操作-學習筆記Excel筆記
- 初識C語言(01)—學習筆記C語言筆記