JVM配置方法

1、調優目的

減少GC的頻率和Full GC的次數

 

2、調優方法

使用jmap、mat等工具進行堆使用情況分析,內存等分析,通過調優參數重複分析使用情況,直到參數最優。

 

3、工具的使用

 

(1)jmap

  觀察運行中的jvm物理內存的佔用情況。

  參數如下:

-heap :打印jvm heap的情況,會列出堆的總體使用情況,還有新生代老生代的內存佔用情況。 
 
-histo: 打印jvm heap的直方圖。其輸出信息包括類名,對象數量,對象佔用大小。 
-histo:live : 同上,但是隻答應存活對象的情況  
-permstat: 打印permanent generation heap情況

  命令使用:

jmap -heap 32575

  可以觀察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的內存使用情況

 

jmap -histo 32575| jmap -histo:live 32575

  可以觀察heap中所有對象的情況(heap中所有生存的對象的情況)。包括對象數量和所佔空間大小。

  輸出內容:

  寫個腳本,可以很快把佔用heap最大的對象找出來,對付內存泄漏特別有效。

  如果結果很多,可以用以下命令輸出到文本文件。

jmap -histo 32575| jmap -histo:live 32575> a.txt

  jmap是一個可以輸出所有內存中對象的工具,甚至可以將VM 中的heap,以二進制輸出成文本。

  命令:jmap -dump:format=b,file=heap.bin

file:保存路徑及文件名

pid:進程編號

 

 

(2)jinfo:可以輸出並修改運行時的java 進程的opts。

jinfo:的用處比較簡單,就是能輸出並修改運行時的java進程的運行參數。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。

 

(3) jps:與unix上的ps類似,用來顯示本地的java進程,可以查看本地運行着幾個java程序,並顯示他們的進程號。

(4) jstat:一個極強的監視VM內存工具。可以用來監視VM內存內的各種堆和非堆的大小及其內存使用量。

jstat工具特別強大,有衆多的可選項,詳細查看堆內各個部分的使用量,以及加載類的數量。使用時,需加上查看進程的進程id,和所選參數。以下詳細介紹各個參數的意義。

jstat -class pid:顯示加載class的數量,及所佔空間等信息。第一列是加載類數量。 
 
jstat -compiler pid:顯示VM實時編譯的數量等信息。

jstat -gc pid:可以顯示gc的信息,查看gc的次數,及時間。其中最後五項,分別是young gc的次數,young gc的時間,full gc的次數,full gc的時間,gc的總時間。 
 
jstat -gccapacity:可以顯示,VM內存中三代(young,old,perm)對象的使用和佔用大小,如:PGCMN顯示的是最小perm的內存使用量,PGCMX顯示的是perm的內存最大使用量,PGC是當前新生成的perm內存佔用量,PC是但前perm內存佔用量。其他的可以根據這個類推, OC是old內純的佔用量。

jstat -gcnew pid:new對象的信息。

jstat -gcnewcapacity pid:new對象的信息及其佔用量。

jstat -gcold pid:old對象的信息。

jstat -gcoldcapacity pid:old對象的信息及其佔用量。

jstat -gcpermcapacity pid: perm對象的信息及其佔用量。

jstat -printcompilation pid:當前VM執行的信息。

jstat -gcutil pid 1000 100 : 1000ms統計一次gc情況統計100次;

 

  除了以上一個參數外,還可以同時加上 兩個數字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,還可以加上-h3每三行顯示一下標題。

 

(5)jconsole:

jconsole是一個用java寫的GUI程序,用來監控VM,並可監控遠程的VM,非常易用,而且功能非常強。使用方法:命令行裏打 jconsole,選則進程就可以了。

 

jstack ( 查看jvm線程運行狀態,是否有死鎖現象等等信息) : jstack pid : thread dump

 

MemoryAnalyzer 查看jmap dump 的內存對象工具 (https://blog.csdn.net/zhanshenzhi2008/article/details/89070049)

 

4、場景模擬

通過設置較小的jvm堆、線程棧、young、older,在程序運行過程中,可以觀察到程序不斷髮送gc,甚至導致程序功能無法正常執行。

 

5、jvm配置方法

(1) 設置Eclipse內存使用情況

     修改eclipse根目錄下的eclipse.ini文件

     -vmargs  //虛擬機設置

     -Xms40m //初始內存

     -Xmx256m //最大內存

   -Xmn16m //最小內存

     -XX:PermSize=128M //非堆內存

     -XX:MaxPermSize=256M

 (2)JVM內存設置

     打開eclipse  window-preferences-Java -Installed JREs -Edit -Default VM Arguments   

     在VM自變量中輸入:-Xmx128m -Xms64m -Xmn32m -Xss16m

 (3)Tomcat內存設置

     打開Tomcat根目錄下的bin文件夾,編輯catalina.bat

     修改爲:set  JAVA_OPTS= -Xms256m -Xmx512m

 

6、配置參數

JVM的Heap分配可以使用-X參數設定,

-Xms 
初始Heap大小

-Xmx 
java heap最大值 

-Xmn 
young generation的heap大小

JVM有2個GC線程
第一個線程負責回收Heap的Young區
第二個線程在Heap不足時,遍歷Heap,將Young 區升級爲Older區

Older區的大小等於-Xmx減去-Xmn,不能將-Xms的值設的過大,因爲第二個線程被迫運行會降低JVM的性能。
爲什麼一些程序頻繁發生GC?

有如下原因:
1.程序內調用了System.gc()或Runtime.gc()。
2.一些中間件軟件調用自己的GC方法,此時需要設置參數禁止這些GC。
3.Java的Heap太小,一般默認的Heap值都很小。
4.頻繁實例化對象,Release對象 此時儘量保存並重用對象,例如使用StringBuffer()和String()。

如果你發現每次GC後,Heap的剩餘空間會是總空間的50%,這表示你的Heap處於健康狀態,許多Server端的Java程序每次GC後最好能有65%的剩餘空間

經驗之談:

1.Server端JVM最好將-Xms和-Xmx設爲相同值。爲了優化GC,最好讓-Xmn值約等於-Xmx的1/3。
2.一個GUI程序最好是每10到20秒間運行一次GC,每次在半秒之內完成。

注意:

1.增加Heap的大小雖然會降低GC的頻率,但也增加了每次GC的時間。並且GC運行時,所有的用戶線程將暫停,也就是GC期間,Java應用程序不做任何工作。
2.Heap大小並不決定進程的內存使用量。進程的內存使用量要大於-Xmx定義的值,因爲Java爲其他任務分配內存,例如每個線程的Stack等。

Stack的設定
每個線程都有他自己的Stack。

-Xss 
每個線程的Stack大小

Stack的大小限制着線程的數量。如果Stack過大就好導致內存溢漏。-Xss參數決定Stack大小,例如-Xss1024K。如果Stack太小,也會導致Stack溢漏。

 

主要通過以下的幾個jvm參數來設置堆內存的: 

-Xmx512m

最大總堆內存,一般設置爲物理內存的1/4

-Xms512m

初始總堆內存,一般將它設置的和最大堆內存一樣大,這樣就不需要根據當前堆使用情況而調整堆的大小了

-Xmn192m

年輕帶堆內存,sun官方推薦爲整個堆的3/8

堆內存的組成

總堆內存 = 年輕帶堆內存 + 年老帶堆內存 + 持久帶堆內存

年輕帶堆內存

對象剛創建出來時放在這裏

年老帶堆內存

對象在被真正會回收之前會先放在這裏

持久帶堆內存

class文件,元數據等放在這裏

-XX:PermSize=128m

持久帶堆的初始大小

-XX:MaxPermSize=128m

持久帶堆的最大大小,eclipse默認爲256m。如果要編譯jdk這種,一定要把這個設的很大,因爲它的類太多了。

 

以上內容僅作實踐記錄參考,文字來自以下博客個人整理。

更多內容參考:

  1. https://blog.csdn.net/happysaz/article/details/81080627
  2. https://www.jianshu.com/p/cbde714e6de8
  3. https://blog.csdn.net/summer_huan/article/details/73649746
  4. https://blog.csdn.net/guangrong1/article/details/79500182
  5. https://blog.csdn.net/zhanshenzhi2008/article/details/89070049
  6. https://www.cnblogs.com/Darrenblog/p/10712125.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章