jvm调优(一)
JVM :Java虛擬機
Java 虛擬機:
數據類型:
數據類型分為兩類:基本類型和引用類型。 基本類型:保存原始值(包括:byte,short,int,long,float,double,Boolean,returnAddres等);引用類型:保存引用值(包括 類類型,借口類型和數組)
堆與棧:(HEAP and STACK)
棧:運行的單位,儲存的是方法
堆:存儲的單位,儲存的是對象
Java中 每一個線程對應一個獨立的線程棧,而堆是所有線程共享的
java中 ,棧的大小 通過 -Xss 來設置,當棧中存儲的數據比較多時,需要適當調整這個值,否則會出現java.lang.StackOverflowError異常。
?------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
jvm結構:
?
1.當eden區 滿了之后,觸發 ygc(young gc):遍歷eden區所有對象,是否還有引用指向他,把沒有指向的對象直接回收掉,還有引用的 放到存活區s0,(這樣伊甸園區變為空,有引用對象進入s0)
備注:在執行ygc ,整個應用程序線程是暫停的
2.第二次eden滿了之后,執行ygc:
? a.遍歷eden區所有對象,是否還有引用指向他,把沒有指向的對象直接回收掉,還有引用的 放到存活區s1
? b.遍歷存活區s0所有對象,是否還有引用指向他,把沒有指向的對象直接回收掉,還有引用的 放到存活區s1
結果:eden和s0都清空
備注:s0與s1 是大小相等,來回互換,不會出現2個都有數據
jvm 默認的參數(可配置),如果ygc15次后 對象還存在,則在下次ygc的時候,該對象放入老年代,大對象,有參數設置的,超過多少后直接進老年代,不進eden
3.第步驟反復多次后,老年代滿了后 ,執行:FULL GC :對整個 堆內存和非堆內存 執行 內存垃圾回收 ,耗時長,會影響性能,盡可能減少full gc 次數?
?結果: eden,s1 執行一次ygc ,老年代沒有引用的干掉
?
4 .正常情況下 ,對象使用后 都應該是可以被回收的,當出現不可回收的對象,并把老年代沾滿后就會出現內存溢出:java.lang.outofmemotyerror:java heap space
5.如果存活區放不了也,會當成大對象 直接從eden放到老年代
?
ycg:eden區滿了,觸發
full gc:老年代滿了;持久帶滿了;system.gc();Runtime.getRuntime().gc() 觸發 還有一些rmi框架會觸發, 還有在執行 jmap -dump 命令 會觸發 full gc?
?
?------------------------------------------------------------------------------------------------------------------------------------------------------------------------
?jdk 命令:
jmap -heap pid ?查看 內存占用 ?(ps -aux|grep java ----pid) \\\jmap 是內存中的命令 ,在~/bin 下要配置環境變量?
?
內存唄占用了 99.99999說明內存 泄露了
-------------------------------
jmap -histo pid >1.txt ??
一般看前 20 就能知道是哪個堵塞 的 cn.test 包名 TsetBean 方法
------------------------------
如果 前 20 沒有的話
jmap -dump:live,format=b,file=heap.bin?<pid>?
live 還存活的對象 沒有 :就是所有對象
file=文件名 可以改?
把 生成的文件 放到MemoryAnalyzer工具中去 ||||||||||||或者 (jhat -J-mx512m xxxx.bin 一般都不用這個了 ):會生成一個端口號 然后在瀏覽器中 輸入 ip:端口?
---------------------------------------------------------------------------------------------------------------------------------------------------------------
jstack ? 當前線程棧正在調取的線程運信息 ?線程運行狀態: new 新建 , RUNABLE 就緒 ,BLOCK 堵塞(死鎖狀態),WAITING 等待,DILE 死亡
jstack pid >2.txt
第一件事就是 搜索 BLOCK 死鎖的線程:線程死鎖錯誤
第二件事就是 搜索 WAITING ,(現象:響應很慢),很多的時候,就要注意(有可能是等待數據庫鏈接池,就要看數據庫鏈接池)
第三件事就是 搜索 RUNABLE, 主要分析 cpu (usr%高的時候)運行的:
先是找cup 運行最高的 進程 (top),然后找線程 top -H -p pid 找到 線程的 pid ,把這個線程 pid 轉換成16進制 再去看線程棧?
或者?
ps -mp pid -o THREAD,tid,time 查看進程中的線程
?
找到 tid ?轉換成 16進制 printf "%x\n" tid
然后 jstack pid |grep 16進制的 tid
(參考文檔:http://note.youdao.com/share/?id=017ee3c5a0d41bffe74521f8dd463237&type=note)
?
備注:cup可以這么分析,io 還有 網絡也可以這么分析,就是再出問題的時間點 看cup在處理什么線程方法?
----------------------------------------------------------------------------------------------------------
jstat -gcutil pid ?xxx(沒個多少秒監聽一次)
查看jvm的使用情況
?------------------------------------------------------------------------------------------------------------
代碼中 可以解決內存溢出:(執行垃圾回收)
System.gc();
Runtime.getRuntime().gc();
?
?--------------------------------------------------------------------------------------------------------------
jconsole
進入 tomcat 下 ?/bin下 ?vim catalina.sh
JAVA_OPTS="-Xms256m?-Xmx256m?-Xss1024K?-XX:PermSize=128m?-XX:MaxPermSize=128m?-Djava.rmi.server.hostname=192.168.189.129?-Dcom.sun.management.jmxremote?-Dcom.sun.management.jmxremote.port=1090?-Dcom.sun.management.jmxremote.ssl=false?-Dcom.sun.management.jmxremote.authenticate=false"??
Xms :最小堆內存256
Xmx:最大堆內存256
Xss:每個線程棧大小
XX:PermSize:初始化持久帶大小
XX:MaxPermSize:最大持久帶大小
Djava.rmi.server.hostname=192.168.189.129 :用rmi協議 監控?192.168.189.129?
com.sun.management.jmxremote.port=1090 端口號1090
Dcom.sun.management.jmxremote.ssl=false?-Dcom.sun.management.jmxremote.authenticate=false :不適用用戶名;不使用安全協議
?
?
?
?
?
轉載于:https://www.cnblogs.com/hanzhao1987/p/6084107.html
總結
- 上一篇: Nginx 多站点配置
- 下一篇: laravel 中创建全局函数 (类似于