jvm原理及調優

1、java內存管理及垃圾回收java

jvm內存組成結構算法

jvm棧由堆、棧、本地方法棧、方法區等部分組成,結構圖以下所示:jvm

技術分享

 

 

(1)堆工具

全部經過new建立的對象的內存都在堆中分配,堆的大小能夠經過-Xmx和-Xms來控制。堆被劃分爲新生代和舊生代,新生代又被進一步劃分紅Eden區和Survivor區,最後Survivor由From Space和To Space組成,結構圖以下所示:spa

新生代。新建的對象都是用新生代分配內存,Eden空間不足的時候,會把存活的對象轉移到Survivor中。新生代大小能夠由-Xmn來控制,也能夠用-XX:SurvivorRatio來控制Eden和Survivor的比例。操作系統

舊生代。用於存放新生代中通過屢次垃圾回收仍然存活的對象。線程

(2)棧3d

每一個線程執行每一個方法的時候都會在棧中申請一個棧幀,每一個棧幀包括局部變量區和操做數棧,用於存放這次方法調用過程當中的臨時變量、參數和中間結果。對象

-Xss:設置每一個線程的棧幀大小。JDK1.5+每一個線程棧幀大小爲1M,通常來講若是棧不是很深的話,1M是絕對夠用的。blog

(3)本地方法棧

用於支持native方法的執行,儲存了每一個native方法調用的狀態。

(4)方法區

存放了要加載的類信息、靜態變量、final類型的常量、字段和方法信息。jvm用持久帶來存放方法區,可經過-XX:PermSize和-XX:PermMaxSize來指定最小值和最大值。

 

垃圾回收按照基本回收策略分

引用計數(Reference Counting)

比較古老的回收算法。原理是此對象有一個引用,即增長一個計數,刪除一個引用則減小一個計數,垃圾回收時,只用收集計數爲0的對象。此算法最致命的是沒法回收循環引用的對象。

標記-清除(Mark-Sweep)

技術分享

此算法執行分兩階段。第一階段從根引用節點開始標記全部被引用的對象,第二個階段遍歷整個堆,把未標記的對象清除。此算法須要暫停這個應用,同時會產生內存碎片。

複製(Copying)

此算法把內存空間劃爲兩個相等的區域,每次只使用其中一個區域。垃圾回收時,遍歷當前使用區域,把正在使用的對象複製到另一個區域中。算法每次只處理正在使用中的對象,所以複製成本比較小,同時複製過去之後還能進行相應的內存整理,不會出現「碎片」的問題。固然,此算法的缺點也是很明顯的,就是須要兩倍內存空間

標記-整理(Mark-Compact)

此算法結合了「標記-清除」和「複製」兩個算法的優勢。也是分兩個階段,第一階段從根節點開始標記全部被引用的對象,第二階段遍歷整個堆,把清除未標記對象而且把存活對象「壓縮」到堆的其中一塊。此算法避免了「標記-清除」的碎片問題,同時也避免了「複製」算法的空間問題。

 

2、jvm內存調優

首先須要注意的是在對jvm內存調優的時候不能只看操做系統級別java進程所佔的內存,這個數值不能準確的反映堆內存的真實佔用狀況。由於GC事後這個值是不會變化的,所以內存調優的時候更多地使用JDK提供的內存查看工具,好比JConsole和Java VitualVM。

對jvm內存的系統級的調優主要的目的是減小GC的頻率和Full GC的次數,過多的GC和Full GC是會佔用不少的系統資源(主要是CPU),影響系統的吞吐量。特別要關注FUll GC,由於它會對整個堆進行整理,致使Full GC通常有如下幾種狀況

舊生代空間不足

Permanent Generation空間不足

system.gc()被顯示調用

調優主要手段是經過控制堆內存的各個部分的比例和GC策略來實現。

各部分比例不良設置致使的後果:

1)新生代設置太小

2)新生代設置過大

3)Survivor設置太小

4)Survivor設置過大

相關文章
相關標籤/搜索