jvm內存模型---方法區,虛擬機棧,本地方法棧,堆,程序計數器java
方法區:又稱永久代,非堆,用於存儲虛擬機加載的類信息,常量,靜態變量,是各個線程共享的內存區域, 算法
-XX:PermSize 設置方法區大小 (在jdk1.7以前叫PermSize 在jdk1.7以後叫metaspace)jvm
-XX:MaxPermSize 設置方法區最大限制性能
虛擬機棧;測試
描述的是Java方法執行的內存模型,每一個方法在執行的時候,都會建立一個「棧幀」,用於存儲局部變量表,操做棧,方法出口等信息,每一個方法被調用執行完的過程就表明着一個「棧幀」在虛擬機棧中從入棧到出棧的過程spa
-Xss2m 這樣設置成2M線程
異常:Fatal:Stack size too small對象
異常的引發通常是線程數目太多blog
本地方法棧:內存
爲一些native方法分配的stack
堆:
也叫作java堆或者GC堆,是java虛擬機所管理的內存中最大的一塊內存區域,也是被各個線程共享的內存區域,在jvm建立時刻建立,該內存存放了對象實例。
jvm調優的重點區域:堆
Young(年輕代)
新生代進一步劃分爲3個區域:一個相對大點的區域,稱爲」伊甸園區(Eden)」;兩個相對小點的區域稱爲」From 倖存區(survivor)」和」To 倖存區(survivor)」。按照規定,新對象會首先分配在 Eden 中(若是新對象過大,會直接分配在老年代中)。在GC中,Eden 中的對象會被移動到survivor中,直至對象知足必定的年紀(定義爲熬過GC的次數),會被移動到老年代。
對象通常出生在Eden區,年輕代GC過程當中,對象在2個倖存區之間移動,若是對象存活到適當的年齡,會被移動到老年代。當對象在老年代死亡時,就須要更高級別的GC,更重量級的GC算法(複製算法不適用於老年代,由於沒有多餘的空間用於複製)
如今應該能理解爲何新生代大小很是重要了(譯者,有另一種說法:新生代大小並不重要,影響GC的因素主要是倖存對象的數量),若是新生代太小,會致使新生對象很快就晉升到老年代中,在老年代中對象很難被回收。若是新生代過大,會發生過多的複製過程。咱們須要找到一個合適大小,不幸的是,要想得到一個合適的大小,只能經過不斷的測試調優。這就須要JVM參數了
-XX:NewSize and -XX:MaxNewSize
就像能夠經過參數(-Xmsand -Xmx) 指定堆大小同樣,能夠經過參數指定新生代大小。設置XX:MaxNewSize 參數時,應該考慮到新生代只是整個堆的一部分,新生代設置的越大,老年代區域就會減小。通常不容許新生代比老年代還大,由於要考慮GC時最壞狀況,全部對象都晉升到老年代。(譯者:會發生OOM錯誤)-XX:MaxNewSize 最大能夠設置爲-Xmx/2.
考慮性能,通常會經過參數-XX:NewSize 設置新生代初始大小。若是知道新生代初始分配的對象大小(通過監控) ,這樣設置會有幫助,能夠節省新生代自動擴展的消耗。
-XX:NewRatio
能夠設置新生代和老年代的相對大小。這種方式的優勢是新生代大小會隨着整個堆大小動態擴展。參數-XX:NewRatio 設置老年代與新生代的比例。例如-XX:NewRatio=3 指定老年代/新生代爲3/1. 老年代佔堆大小的3/4 ,新生代佔1/4 .
Tenured(年老代)
年老代存放從年輕代存活的對象。通常來講年老代存放的都是生命期較長的對象。
Perm(持久代)----同時也叫方法區
用 於存放靜態文件,現在Java類、方法等。持久代對垃圾回收沒有顯著影響,可是有些應用可能動態生成或者調用一些class,例如Hibernate等, 在這種時候須要設置一個比較大的持久代空間來存放這些運行過程當中新增的類。持久代大小經過-XX:MaxPermSize=進行設置。
持久代通常固定大小爲64m