【轉】jvm 記憶體模型及記憶體調優

來源:互聯網
上載者:User

標籤:

一,JVM記憶體模型概括 

 

還有一個寄存器,線程運行於其上面

 

1.程式計數器 
記錄線程的執行位置,線程私人記憶體,唯一一個在Java虛擬機器規範中沒有規定任何OutOfMemoryError情況的地區

2.線程棧(VM stack)

棧的預設大小是1M

-Xss2m 這樣設定成2M

異常 :Fatal: Stack size too small

異常的引起一般是線程數目太多


3.本地方法棧(native stack)


即為一些Native方法分配的stack

異常:java.lang.OutOfMemoryError: unable to create new native thread

一般也是由線程太多引起,增加棧空間,同上方法

 

4.堆(heap),程式可用堆

自JConsole 
每個線程的棧都是該線程私人的,堆則是所有線程共用的

這裡說的堆,主要指程式能控制的,包括

The New Generational Heap,預設4M,此地區一般為JVM記憶體的1/15大小

此代分為Eden space區,Survivo space區可以看成emptySurvivo區,Survivor區,

當new 一個對象時,首先是在Eden space區,當Eden space區滿時,Survivor space區進行記憶體回收(此處複製演算法),當對象在Survivo space區經過幾次回收Tenured Generation

複製演算法,每次演算法開始都得停止當前所有的線程,然後把Survivor區的所有活躍的對象複製到emptySurvivo區,然後對Survivor區空間進行清除變成emptySurvivo,以前的emptySurvivo成為了Survivor區。(互換)

 

Tenured Generation,

此處儲存年老代的對象,此處的記憶體回收採用The Mark and Sweep 演算法

GC標記演算法/清理演算法(The Mark and Sweep algorithms)進行回收,從引用進行標記,然後按照引用的程度或無引用到的對象進行回收,然後再對清除了的記憶體進行合并.

 

關於GC,因為GC主要就是對堆的回收,當然還有常量池和永久代,所以此處總結下GC

GC策略介紹

對於GC在 HotSpot VM 常用的有三種:

1.serial collector,單線程收集器,回收時都需要暫停當前線程,長時間等待,

配置

Client下預設

強制加上 -XX:+UseSerialGC

2.parallel collector( throughput collector ),並行收集器,或叫多線程的收集

年輕代:暫停應用程式,多個垃圾收集線程並行的複製收集。
年老代:暫停應用程式, 多個垃圾收集線程並行的複製收集。

server下預設,具體配置

設定並行收集的線程數目,如20個線程,-XX:ParallelGCThreads=20

配置年輕代為並行收集  -XX:+UseParallelGC.

配置年老代垃圾收集方式為並行收集(JDK6.0開始支援)-XX:+UseParallelOldGC

設定暫停時間,設定每次年輕代記憶體回收的最長時間如果無法滿足此時間,JVM會自動調整年輕代大小,以滿足此值,如 -XX:MaxGCPauseMillis= 100, 

設定輸送量,輸送量為記憶體回收時間與非記憶體回收時間的比值  -XX:GCTimeRatio 來調整GC的時間

 

3.concurrent collector(concurrent low pause collector),並發收集器

年輕代:同樣是暫停應用程式,多個垃圾收集線程並行的複製收集。
年老代:和並行的區別在這,只是在初始標記(initial mark)和二次標記(remark)時需要stop-the-world。但收集時時間很長,所以不能等年輕代滿後再開始清理.

使用啟動並發收集器 -XX:+UseConcMarkSweepGC

XX:CMSInitiatingOccupancyFraction=指定還有多少剩餘堆時開始執行並發收集

 

  • 根據官方文檔,他們倆個需要在多CPU的情況下,才能發揮作用。在一個CPU的情況下,會不如預設的serial collector,因為線程管理需要耗費CPU資源。而在兩個CPU的情況下,也提高不大。只是在更多CPU的情況下,才會有所提高。當然 concurrent low pause collector有一種模式可以在CPU較少的機器上,提供儘可能少的停頓的模式,見CMS GC Incremental mode。
  • 當要使用throughput collector時,在java opt裡加上-XX:+UseParallelGC,啟動throughput collector收集。也可加上-XX:ParallelGCThreads=<desired number>來改變線程數。還有兩個參數 -XX:MaxGCPauseMillis=<nnn>和 -XX:GCTimeRatio=<nnn>,MaxGCPauseMillis=<nnn>用來控制最大暫停時間,而-XX: GCTimeRatio可以提高GC說占CPU的比,以最大話的減小heap。

- 此段引自 HotSpot VM GC 的種類 

 

GC的觸發條件(基於serial collector,不同的GC策略略有不同,基本都差不多)

對於new generation來說,當eden區的對象空大於Survivor0(假設為from)的free空間時,會發生minor gc,即對整個Survivor0區,Survivor1區進行一個複製演算法記憶體回收,並且部分對象轉到Old Generation

當new generation滿了(即eden區+Survivor0區大於Old Generation的free空間時),將發生major gc,即對New Generation和Old Generation兩代都進行記憶體回收

當然還一種程式調用system.gc(),但此方法也不一定會調用,只是建議

所以得出,如果JVM的設定記憶體過大,發生GC的回收頻率將越小,但是回收的時間越長(特別對new generation進行複製演算法的複製時是需要停止當前所有線程的),所以並不是說JVM的記憶體設定的越大越好,得根據實際情況進行最佳化。

 

異常 java.lang.OutOfMemoryError: Java heap space

一般是由於記憶體回收後,old generation裡空間也不夠用了

 

 

堆記憶體的相關參數設定

預設值(基於-server)

-server時最大堆記憶體是實體記憶體的1/4,但小於1G. JDK 1.5以前是64M

(官方: Smaller of 1/4th of the physical memory or 1GB.Before J2SE 5.0, the default maximum heap size was 64MB.)

-client 小一倍

參數設定

-Xms128m 
表示JVM Heap(堆記憶體)最小尺寸128MB,初始分配 
-Xmx512m 
表示JVM Heap(堆記憶體)最大允許的尺寸256MB,按需分配

 

new Generation與Old Generation的比例,預設為1:2,即為2

-XX:NewRatio= 參數可以設定(也可以-XX:NewSize和-XX:MaxNewsize設定新域的初始值和最大值)

 

Eden與Survivor的比例,預設為32

-XX:SurvivorRation=參數可以設定

 

當對象預設經過1次New Generation 就轉入Old Generation(這個不同文章上不同,待我確定)

-XX:MaxTenuringThreshold=參數可以設定 (預設0)

用-XX:+PrintTenuringDistributio可以查看值

 


5.方法區,永久代(Perm Space)

其實也可與看成堆記憶體的一部分,看成永久代(Perm Space),但GC也會回收,但很少回收,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料,比如一個int x,在不同的環境中是不同的,此資訊就存在方法區

 

異常:java.lang.OutOfMemoryError: PermGen space

引起,一般是太多的類資訊,比如應用spring很多反射資訊,可以適度設定大點

方法區或永生代相關設定

-XX:PermSize=64MB 最小尺寸,初始分配 
-XX:MaxPermSize=256MB 最大允許分配尺寸,按需分配

XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled 設定垃圾不回收

預設大小

-server選項下預設MaxPermSize為64m 
-client選項下預設MaxPermSize為32m

 


6.常量池 
Class檔案中除了有類的版本、欄位、方法、介面等描述等資訊外,還有一項資訊是常量表(constant_pool table),用於存放編譯期已可知的常量,這部分內容將在類載入後進入方法區(永久代)存放。但是Java語言並不要求常量一定只有編譯期預置入Class的常量表的內容才能進入方法區常量池,運行期間也可將新內容放入常量池(最典型的String.intern()方法)。

GC的作用主要是用來卸載類和回收常量池,當然有部分方法區,即使永久代(Perm Space)也會一定的回收

 

7.native記憶體區“Code Cache”(non-heap)

這個沒畫出來,但通過工具可以看到,用於存放編譯和儲存本地代碼(native code)的記憶體

 

 

 

二,對TOMCAT監控調優

1,監控TOMCAT記憶體

JConsole,JDK內建

直接在命令列輸入JConsole,開啟JConsole,如堆那個圖,就可以監控了

遠程監控,需要在啟動程式時,配置 com.sun.management.jmxremote 即可

比如tomcat,

開啟%tomcat_home%/bin/catalina.bat (linux下是catalina.sh),在JAVA_OPTS=%JAVA_OPTS%後加上參數

-Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

然後開啟JConsole

然後串連即可

如開啟堆圖,可以找到上面說的各個部分

 

Eden Space (heap): 記憶體最初從這個線程池分配給大部分對象。

Survivor Space(heap):用於儲存從Eden Space copy的對象,複製演算法,分兩部分Survivor

Tenured Generation (heap):用於保持已經在 survivor space記憶體池中存在了一段時間的對象。

Perm Generation (non-heap): 方法區,儲存虛擬機器自己的靜態(refective)資料,例如類(class)和方法(method)對象。Java虛擬機器共用這些類資料。這個地區被分割為唯讀和唯寫的

Code Cache(non-heap):HotSpot Java虛擬機器包括一個用於編譯和儲存本地代碼(native code)的記憶體,叫做“代碼緩衝區”(code cache)

 

2,列印Tomcat的日誌

在前面繼續加上參數 -Xloggc:%TOMCAT_HOME%\logs\tomcat_gc.log  , 把LOG記錄檔輸出到tomcat_gc.log 

開啟日誌如下

0.755: [GC 11747K->1664K(62848K), 0.0039655 secs]0.759: [Full GC 1664K->1604K(62848K), 0.0241215 secs]

如果不滿意,可以進行調優,參數如文中上面參數所示,直接設定於JAVA_OTPS即可

3,利用JSTA查看GC情況

 

詳細 附上

JConsole 遠程監控Tomcat服務

TOMCAT參數詳解

jstat 使用

其他工具

 

JProfiler :商業軟體,需要付費。功能強大。詳細說明參考

VisualVM :JDK內建,功能強大,與JProfiler類似,官網地址下載http://visualvm.java.net/download.html(當然JDK7現在都內建了,在jdk1.7.0_10\bin裡)

JConsole和VisualVM 在JDK都內建了 o(∩_∩)o 哈哈  感覺JProfiler這些收費的挺尷尬

 

OK,記憶體回收和調優原理打完收工,大概清楚 ,調優了就有方向了,具體參數可以查文檔等

【轉】jvm 記憶體模型及記憶體調優

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.