1. 程式人生 > >通過jstat、jmap對java程式進行效能調優

通過jstat、jmap對java程式進行效能調優

1. 背景

硬體供應商多次反映,在tomcat啟動一段時間後,經常出現cpu佔用率100%,且重啟前一直保持在100%的情況。在重啟後cpu佔用率回落,但是一段時間後再次出現問題。

下圖為cpu佔用率100%時使用top命令的截圖,可以看到java程序的cpu佔用率幾經幾乎達到了400%(伺服器為4核cpu)

<1><1>

2.問題定位

2.1問題猜測

對於cpu佔用率100%的情況,產生以下兩種猜測:

a. 程式長時間佔用系統IO,導致CPU佔用率100%

b.程式存在嚴重記憶體洩露,導致jvm頻繁執行full GC,從而使cpu佔用率提高,造成伺服器假死

2.2jvm的記憶體管理和垃圾回收機制

java對記憶體的管理主要分為兩種:棧(stack)和堆(heap) 方法區,程式計數器等不做討論

stack: 在每個執行緒啟動時由jvm自動分配固定大小的地址,stack內主要儲存操作符,值物件(int,float等基礎資料型別),和引用物件的指標由於stack固定大小,且主要操作為push和pop,並不涉及到垃圾回收等問題,因此不做展開。

heap:堆線上程執行過程中自動分配大小,大小可以隨時改變,主要用於儲存物件(Object),物件在結束生命週期結束之後便會由JVM的垃圾回收機制自動進行回收堆可分為3大部分年輕代(Young Generation)、年老代(Old Generation)和持久代(Permanent Generation)。

年輕代:年輕代又可分為3個小區:Eden,兩個等大的Survior區(from 和 to)。其中Eden主要存放新建的物件,當Eden區無法再存放更多的物件時,jvm會發起年輕代GC(Minor GC),釋放Eden中的物件,Minor GC的特點是發生頻率高,執行速度也極快,對系統效率的影響並不是很大。當Eden區中的物件經過一次Minor GC仍然沒有被釋放時,這部分物件將被移入Survior區(物件可能進入from區,也可能進入to區,有具體演算法,此處不做展開)。當Survior區中的物件經歷過數次的Minor GC之後仍然存活,將被移入年老代。

年老代:年老代中用來存放從年輕代過來的長時間使用的物件,大部分的JVM記憶體溢位錯誤均發生在這個區域。當年老代被過度佔用,無法存放下更多的資料時,jvm會發起一次年老代GC(Major GC\Full GC),該型別GC會釋放年老代中的資源,雖然該GC觸發頻率很低,但是對硬體資源的消耗較高,且Full GC過程中會暫停該執行緒的

執行。如果系統中存在記憶體洩露,頻繁的觸發Full GC,將會嚴重的佔用伺服器資源,造成應用的假死,這也是我之前猜測b的依據。

持久代:持久代中用於存放jvm的反射類等,如class等,此區域對GC的影響不大,也不大會發生記憶體溢位的情況。

下圖是引用網上的一張圖片,更形象的描述了heap區的構成

<2><2>

2.3jstat、jmap實戰

ok,在弄清楚jvm的GC機制之後,就有了努力的方向了,為了弄清楚GC具體的工作情況,就要使用到jstat命令了。

jstat(Java Virtual Machine Statistics Monitoring Tool)是jdk自帶的監控工具,位置在%JAVA_HOME%/bin 下,命令使用方法為

 jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

下圖是我對系統中tomcat程序的監控情況

<3><3>

<4><4>

命令中 -gcutil表示統計GC情況,5125為tomcat的pid,10000表示沒10s統計一次,5表示一共統計5次

結果中s0為from區,s1為to區,E為Eden區,O為Old區,P為Permanent區,YGC為yong GC次數,YGCT為yong GC執行的總時間,FGC為Full GC次數,FGCT為Full GC總時間,GCT為GC總時間。

上面圖<3>為cpu佔用率高時的截圖,圖<4>為正常情況下截圖。

很明顯的看到GC次數相差不大的情況下,GC耗時存在很大的差距,推測此時系統中可能存在記憶體洩漏的情況。

為了確定jvm中具體有哪些生存的物件,就需要用到jdk自帶的另一個監控工具,jmap了

jmap(Memory Map)用於監控系統記憶體中存活的物件。

使用命令: jmap -histo:live 5125>> /opt/jmap.txt  

如果要dump所有物件,可以通過命令:

jmap -dump:file=a.hprof pid

其中5125為pid ,由於資料較多,將資料儲存在txt檔案中進行分析,下圖列出了對記憶體佔用排名前幾的物件

<5><5>

一眼看去,String物件穩居第一,好吧,專案中對String的處理確實有不少問題,但是,排名第三的這是什麼東西?!

在程式碼中一查,這個物件只在一個上傳檔案中的Servlet中被用到了一次,很明顯的記憶體洩漏!

3.問題解決

很明顯,jspsmart這個外掛正是記憶體洩漏的元凶,網上查詢資料之後確定,jspsmart由於自身bug,在長時間執行後會產生兩個嚴重問題: a. 客戶端在未完成上傳時便主動終止了上傳操作,此時客戶端不再上傳檔案,但是服務端仍然會佔用InputStream,並且不會主動釋放,造成cpu佔用率100%,猜測a證實 b. 客戶上傳的檔案損壞,在建立File物件時無法找到檔案終止標識,因此一直在建立新的File物件,造成記憶體洩漏。 由此,伺服器記憶體溢位和cpu佔用率100%兩個問題都找到了關鍵所在,接下來的工作就像對簡單了,使用apache的開源專案commons-upload替換原來的jspsmart來完成檔案上傳的工作,替換過後,系統資源佔用正常,附上bug修復後的jmap截圖 <6><6>

相關推薦

通過jstatjmapjava程式進行效能調

1. 背景 硬體供應商多次反映,在tomcat啟動一段時間後,經常出現cpu佔用率100%,且重啟前一直保持在100%的情況。在重啟後cpu佔用率回落,但是一段時間後再次出現問題。 下圖為cpu佔用率100%時使用top命令的截圖,可以看到java程序的c

TPTP(Java Profiling Tools外掛)Java程式進行效能測試

來源:http://blog.csdn.net/wsj19890201/article/details/5492517 概述:Eclipse Test & Performance Tools Platform (TPTP) 的效能測試工具 (Profiling t

Web 應用程式進行效能調

動態的 Web 應用程式能夠儲存大量資訊,讓使用者能夠通過熟悉的介面立即訪問這些資訊。但是,隨著應用程式越來越受歡迎,可能會發現對請求的響應速度沒有以前那麼快了。開發人員應該瞭解 Web 應用程式處理 Web 請求的方式,知道在 Web 應用程式開發中可以做什麼,不能做什麼,

JMeter學習(十七)JMeter測試Java 目的:Java程式進行測試

目的:對Java程式進行測試   目錄 一、核心步驟 二、例項 三、JMeter Java Sampler介紹 四、自帶Java Request Sampler   一、核心步驟 1.建立一個Java工程; 2.將JMeter的lib目錄下

AngularJS進行效能調的7個建議

AnglarJS作為一款優秀的Web框架,可大大簡化前端開發的負擔。近日Sebastian Fröstl在一篇博文《AngularJS Performance Tuning for Long Lists》中表示AnglarJS在處理包含複雜資料結構的大型列表時,其執行速度

第1章 執行在YARN上的Spark進行效能調

1.1.1執行環境Jar包管理及和資料本地性原理在YARN上執行Spark需要在Spark-env.sh或環境變數中配置HADOOP_CONF_DIR或YARN_CONF_DIR目錄指向Hadoop的配置檔案。Spark-default.conf中配置Spark.YARN.j

Java程式為什麼需要調(《大話Java效能優化》第一章第一節)

1.1為什麼需要調優經歷了多年的發展,Java已由一門單純的計算機程式語言,演變為一套強大的技術體系平臺。根據不同的技術規範,Java設計者們將Java劃分為3種結構獨立但卻又彼此依賴的技術體系分支,分別是Java SE、Java EE和Java ME,其中Java EE被廣泛使用在企業級領域,出了包括Jav

kafka叢集基於永續性指標進行效能調實踐-kafka 商業環境實戰

本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。期待加入IOT時代最具戰鬥力的團隊。QQ郵箱地址:[email protected],如有任何學術交流,可隨時聯絡

kafka叢集基於延時指標進行效能調實踐-kafka 商業環境實戰

本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。期待加入IOT時代最具戰鬥力的團隊。QQ郵箱地址:[email protected],如有任何學術交流,可隨時聯絡

kafka叢集基於吞吐量指標進行效能調實踐-kafka 商業環境實戰

本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。期待加入IOT時代最具戰鬥力的團隊。QQ郵箱地址:[email protected],如有任何學術交流,可隨時聯絡

kafka叢集基於可用性指標進行效能調實踐-kafka 商業環境實戰

版權宣告:本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。期待加入IOT時代最具戰鬥力的團隊。QQ郵箱地址:[email protected],如有任何學術交流,

關於Java虛擬機器效能調方法的一些分析

關於效能調優: 1 需要一個性能探測器,找到呼叫最頻繁的程式碼段,優化這部分程式碼(優化演算法) 2 往往1%的程式碼執行時間佔99%。所以優化這些程式碼就能事半功倍。 3 最好是能看懂編譯後的程式碼,這樣分析最徹底。 Java的效能分析使用JProfiler 堆疊分析使用的Jstack Java效能調優 S

php啟用Opcache進行效能調

     php5.5以上版本已經內建了zend OpCache。通過配置zend opCache模組,將預編譯的php位元組碼載入到共存記憶體中,省去了每次載入php檔案和編譯php程式碼的開銷,可以極大提高php效能。     opcache模組常用配置如下 #配置

(一)solr 7.31版本window系統全程安裝搭建,涵蓋專案用到的大部分配置,常用查詢,solr多條件查詢排序,配置資料庫,定時同步,全量與增量更新,使用solrJ在java程式進行增刪改查

前言:由於專案最近在做淘寶客商品資訊查詢這一塊,做搜尋引擎,離不開全文搜尋伺服器,我這裡選擇了solr。solr的好處可以自行百科,這裡主要是講解技術。這篇文章主要講解window的安裝和使用。若大家感興趣或者專案用到,希望你能跟著我的步驟進行下去,如果遇到問題,可以後續看下我在最底下的問題

jmeter通過jmeter-pluginsjconsole系統資源進行監控

Jmeter監控系統資源 Jmeter監聽器選項不能滿足我們對系統資源一些效能引數進行監控,我們可以通過jmeter的控制元件去對記憶體、CPU、磁碟I/O等效能進行監控; Jmeter-plugin

使用MATLAB程式Simulink控制系統進行模擬

一、 採用Simulink建立系統模擬   如圖所示建立一階、二階系統控制模型,其引數雙擊Zero-Pole可以設定,分子分母採用零點、極點的方式改變,在沒有任何零極點時為[],即裡面不寫。s前的係數也可以自己設計。                    圖1,一階、二階系統

面試官問我:平常如何你的Java程式進行調

作者:張俊城, 郭理勇, 劉建 來源:http://t.cn/AiCTERJz ​ Java 應用效能優化是一個老生常談的話題

201671010127 2016—2017-2 通過一個小程序Java的再認識。

實現 字符串和字符 代碼 generated 字符串的操作 以及 math ext 兩個   學習了將近四周的Java語言,對於Java語言,我也有了更進一步的理解,出於對Java語言的喜愛,我總是喜歡沒事的時候,自己敲一些很簡單的代碼,一邊學習Java語言,一邊對比C語言

java方法進行功能增強的三種方法

demo1 static @override 反射 調用方法 demo over 使用詳解 知識 對java方法進行功能增強的方法 1.通過繼承的方式   對哪個類中的方法進行增強,可以采用繼承那個類的方式。通過繼承該類,可以重寫方法,如果還需要老方法的一些功能,使用sup

cmd命令java程序進行編譯時出現:編碼GBK的不可映射字符

原因 格式轉化 ava str cmd命令 轉化 code 有用 unicode 原因:由於JDK是國際版的,在編譯的時候,如果我們沒有用-encoding參數指定JAVA源程序的編碼格式,則java.exe首先獲得我們才做系統默認采用的編碼格式,也即在編譯JAVA程序時,