兩張圖均以《深刻理解java虛擬機》爲參考製做的,第一張圖對java內存進行區域上的劃分,第二張圖主要是從運行的角度對棧作出進一步的說明html
由第二張圖能夠更深刻的理解線程私有的含義,虛擬機棧並非一整塊區域,而是由衆多的運行的線程組成java
在虛擬機啓動時建立,此內存區域惟一目的就是存放對象實例,幾乎全部的對象實例都在堆上分配,也是垃圾收集器管理的主要區域,也叫GC堆docker
存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據,別名Non-Heap,非堆,JDK8時已經完全沒有了永久代,將方法區直接放在一個與堆不相連的本地的直接內存區域,這個區域被叫作元空間,網絡
Hotspot虛擬機直接就把本地方法棧和虛擬機棧合二爲一函數
相較於Class文件常量池,具備動態性,常量並不必定只有在編譯期產生,運行時也可將新產生的常量放入池中,存儲字面量、符號引用、直接引用的地址等信息,須要注意的是,post
Hotspot在jdk7中已經把本來放在永久代的字符串常量池移出,放在堆內存裏,JDK8時因已經完全沒有了永久代,將方法區(包括運行時常量池)直接放在一個與堆不相連的本地直接內存區域,這個區域被叫作元空間url
jdk6及之前,都是放在方法區的,jdk7時將字符串常量池移至堆區,jdk8時雖然方法區已取消,運行時常量池移至元空間中,但字符串常量池依舊留在堆中spa
class文件中的一項信息存放編譯期生成的各類字面量和符號引用,這部份內容會在類加載後進入方法區的運行時常量池中線程
注意:關於JDK8中,方法區、運行時常量池、字符串常量池的關聯關係可參考JDK8-廢棄永久代(PermGen)迎來元空間(Metaspace)。日誌
虛擬機棧用於執行普通的Java方法,本地方法棧用於執行本地方法(Native方法),Hotspot虛擬機直接就把本地方法棧和虛擬機棧合二爲一
每一個方法在執行的同時都會建立一個棧幀,每一個棧幀裏存儲着局部變量表、操做數棧 動態連接、方法出口等信息
局部變量表
所需空間在編譯期完成分配,當進入一個方法時局部變量空間是 徹底肯定的,方法運行期間不會改變,局部變量表裏存放着編譯期可知的各類基本類型、 對象引用和returnAddress類型(執行一條字節碼指令的地址)
垃圾回收,對年輕代的垃圾回收即爲minor GC,也叫young GC
存在於堆中,可是線程私有,-xx:+/-UseTLAB 是否使用本地線程緩衝
NIO引入一種基於通道與緩衝區的IO方式,使用Native函數庫直接分配堆外內存, 而後經過一個存儲在java堆中的DirectByteBuffer對象的引用進行操做
JDK8及之後,因爲類的元數據分配在本地內存中,元空間的最大可分配空間就是系統可用內存空間。所以,咱們就不會遇到永久代存在時的內存溢出錯誤,也不會出現泄漏的數據移到交換區這樣的事情。
最終用戶能夠爲元空間設置一個可用空間最大值,若是不進行設置,JVM 會自動根據類的元數據大小動態增長元空間的容量。這裏須要注意的是,若是在docker容器裏,那麼默認的元空間大小爲物理機的內存大小,
此時若是設置了容器的limit,且元空間內存溢出,則將會由系統kill掉,而在容器裏的日誌中沒有kill的信息。
在元空間中,類和其元數據的生命週期和其對應的類加載器是相同的。換句話說,只要類加載器存活,其加載的類的元數據也是存活的,於是不會被回收掉。在元空間的回收過程當中沒有重定位和壓縮等操做,
可是元空間內的元數據會進行掃描來肯定 Java 引用。
程序在申請內存後,對象沒有被GC所回收,它始終佔用內存,內存泄漏的堆積最終會形成內存溢出。
程序運行過程當中沒法申請到足夠的內存而致使的一種錯誤。內存溢出一般發生於OLD段或Perm段垃圾回收後,仍然無內存空間容納新的Java對象的狀況。一般都是因爲內存泄露致使堆棧內存不斷增大,從而引起內存溢出
圖片摘自網絡
-Xms:堆的最小值
-Xmx:堆的最大值
以上兩個值設置成同樣的可避免自動擴展
-Xmn:年輕代大小
-XX:MaxNewSize:年輕代的最大值
-XX:NewSize:年輕代的最小值
老年代的空間大小沒有直接設置的參數
-Xms 減去 -XX:MaxNewSize,即爲老年代的空間大小
-XX:MaxPermSize:永久代的最大值,JDK8後無效
-XX:PermSize:永久代的最小值,JDK8後無效
-XX:MaxMetaspaceSize:元空間的最大值,JDK8及之後
‑XX:MinMetaspaceFreeRatio:元空間空閒比例的最小值
‑XX:MaxMetaspaceFreeRatio:元空間空閒比例的最大值
-Xss:設置每一個線程的堆棧大小
-XX:MaxDirectMemorySize:設置本機直接內存的最大值,默認與堆最大值同樣
參考:
《深刻理解java虛擬機》