java 线上运维_一次java应用线上运维实战
背景:今天深圳項目出現負載狂飆的情況,由我負責主要的運維,簡單記錄運維的情況
一、首先使用top命令查看java進程對資源的使用情況。
通過%CPU、%MEM的參數信息可以看出當前進程瘋狂占用CPU(使用量最高已經彪到了百分之3000多),內存使用情況占用到80%以上,8G內存。
二、首先先著手分析內存會不會溢出,因為當前zabbix報警系統的出發點是內存大于80%將會觸發報警
首先使用 jmap -heap PID 看進行堆使用情況,根據Heap Usage的數據顯示,當前堆內存使用情況還有剩余1G的內存空間,其中 700m的空閑空間在分布新生待,300m的空間分布在老年代。
附上JVM 內存圖
在這里可以得出結論,堆內存空間還是相對充足,不會出現堆內存溢出的情況。
思考:jvm內存占用情況=堆內存使用情況+非堆內存使用情況
接下里驗證非堆內存使用的情況(也是上圖的右邊區域)
jstat -gcmetacapacity PID 看meta space 使用情況
結果發現metaspace 占用的內存其實不高,大概只有200m左右
ps -o rss vsz -p PID 根據rss值確認實際占用內容多少
RSZ是Resident Set Size,常駐內存大小,即進程實際占用的物理內存大小, 在現在這個例子當中,RSZ和實際堆內存占用差了1個多G,根據網上資料顯示這1個多G的內存組成分別為:
1.JVM本身需要的內存,包括其加載的第三方庫以及這些庫分配的內存
2.NIO的DirectBuffer是分配的native memory
3.內存映射文件,包括JVM加載的一些JAR和第三方庫,以及程序內部用到的。上面 pmap 輸出的內容里,有一些靜態文件所占用的大小不在Java的heap里,因此作為一個Web服務器,趕緊把靜態文件從這個Web服務器中人移開吧,放到nginx或者CDN里去吧。
4.JIT, JVM會將Class編譯成native代碼,這些內存也不會少,如果使用了Spring的AOP,CGLIB會生成更多的類,JIT的內存開銷也會隨之變大,而且Class本身JVM的GC會將其放到Perm Generation里去,很難被回收掉,面對這種情況,應該讓JVM使用ConcurrentMarkSweep GC,并啟用這個GC的相關參數允許將不使用的class從Perm Generation中移除, 參數配置: -XX:+UseConcMarkSweepGC -X:+CMSPermGenSweepingEnabled -X:+CMSClassUnloadingEnabled,如果不需要移除而Perm Generation空間不夠,可以加大一點: -X:PermSize=256M -X:MaxPermSize=512M
5.JNI,一些JNI接口調用的native庫也會分配一些內存,如果遇到JNI庫的內存泄露,可以使用valgrind等內存泄露工具來檢測
6.線程棧,每個線程都會有自己的??臻g,如果線程一多,這個的開銷就很明顯了
因為這次負責的是運維工作,無法實際上從代碼層面解決問題,所以采取的抑制內存報警的策略是通過調低堆內存的最大空間,因為堆內存的使用空間還剩很多,另外,檢測到了其中一臺機子是16g內存,在80%使用時已經報警,實際到了報警情況還有剩余4g的內存空間,是很大的,所以結合上述參考的情況,把-Xms的值調小,原來是-Xms=-Xmx=12g,讓內存在被使用時才被占用。
另外對于CPU占用過高的問題,可以通過打印線程棧的方式找到對應的線程:
top -Hp PID 找出最高線程編號
print “%x\n” 28178 獲取線程16進制地址
jstack PID |grep -10 (線程十六進制編號)
找出具體類,聯系產品組進行修改
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的java 线上运维_一次java应用线上运维实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java线程运行无限次_java程序运行
- 下一篇: java中ra怎么解释_JAVA个人相关