性能測試項目總結(jié)之內(nèi)存泄露和內(nèi)存溢出_第1頁
性能測試項目總結(jié)之內(nèi)存泄露和內(nèi)存溢出_第2頁
性能測試項目總結(jié)之內(nèi)存泄露和內(nèi)存溢出_第3頁
性能測試項目總結(jié)之內(nèi)存泄露和內(nèi)存溢出_第4頁
性能測試項目總結(jié)之內(nèi)存泄露和內(nèi)存溢出_第5頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、最近大家對性能測試的內(nèi)存監(jiān)控挺感興趣的,有好多文章都是關(guān)于內(nèi)存泄露的。剛剛做完了一個項目的性能測試,“有幸”也遇到了內(nèi)存泄露的案例,所以在此和大家分享一下。主要從以下幾部分來說明,關(guān)于內(nèi)存和內(nèi)存泄露、溢出的概念,區(qū)分內(nèi)存泄露和內(nèi)存溢出;內(nèi)存的區(qū)域劃分,了解GC回收機(jī)制;重點(diǎn)關(guān)注如何去監(jiān)控和發(fā)現(xiàn)內(nèi)存問題;此外分析出問題還要如何解決內(nèi)存問題。下面就開始本篇的內(nèi)容第一部分 概念眾所周知,java中的內(nèi)存java虛擬機(jī)自己去管理的,他不想C+需要自己去釋放?;\統(tǒng)地去講,java的內(nèi)存分配分為兩個部分,一個是數(shù)據(jù) 堆,一個是棧。程序在運(yùn)行的時候一般分配數(shù)據(jù)堆,把局部的臨時的變量都放進(jìn)去,生命周期和進(jìn)程有

2、關(guān)系。但是如果程序員聲明了static的變量,就直接在 棧中運(yùn)行的,進(jìn)程銷毀了,不一定會銷毀static變量。另外為了保證java內(nèi)存不會溢出,java中有垃圾回收機(jī)制。 System.gc(即垃圾收集機(jī)制是指jvm用于釋放那些不再使用的對象所占用的內(nèi)存。java語言并不要求jvm有g(shù)c,也沒有規(guī)定gc如何工作。 垃圾收集的目的在于清除不再使用的對象。gc通過確定對象是否被活動對象引用來確定是否收集該對象。而其中,內(nèi)存溢出就是你要求分配的java虛擬機(jī)內(nèi)存超出了系統(tǒng)能給你的,系統(tǒng)不能滿足需求,于是產(chǎn)生溢出。  內(nèi)存泄漏是指你向系統(tǒng)申請分配內(nèi)存進(jìn)行使用(new,可是使用完了以

3、后卻不歸還(delete,結(jié)果你申請到的那塊內(nèi)存你自己也不能再訪問,該塊已分 配出來的內(nèi)存也無法再使用,隨著服務(wù)器內(nèi)存的不斷消耗,而無法使用的內(nèi)存越來越多,系統(tǒng)也不能再次將它分配給需要的程序,產(chǎn)生泄露。一直下去,程序也逐漸 無內(nèi)存使用,就會溢出。第二部分 原理JAVA垃圾回收及對內(nèi)存區(qū)劃分在Java虛擬機(jī)規(guī)范中,提及了如下幾種類型的內(nèi)存空間:棧內(nèi)存(Stack):每個線程私有的。堆內(nèi)存(Heap):所有線程公用的。方法區(qū)(Method Area):有點(diǎn)像以前常說的“進(jìn)程代碼段”,這里面存放了每個加載類的反射信息、類函數(shù)的代碼、編譯時常量等信息。原生方法棧(Native Method Stack

4、):主要用于JNI中的原生代碼,平時很少涉及。而Java的使用的是堆內(nèi)存,java堆是一個運(yùn)行時數(shù)據(jù)區(qū),類的實例(對象從中分配空間。Java虛擬機(jī)(JVM的堆中儲存著正在運(yùn)行的應(yīng)用程序所建立的所有對象,“垃圾回收”也是主要是和堆內(nèi)存(Heap)有關(guān)。垃圾回收的概念就是JAVA虛擬機(jī)(JVM)回收那些不再被引用的對象內(nèi)存的過程。一般我們認(rèn)為正在被引用的對象狀態(tài)為“alive”,而沒有被應(yīng) 用或者取不到引用屬性的對象狀態(tài)為“dead”。垃圾回收是一個釋放處于”dead”狀態(tài)的對象的內(nèi)存的過程。而垃圾回收的規(guī)則和算法被動態(tài)的作用于應(yīng)用 運(yùn)行當(dāng)中,自動回收。JVM的垃圾回收器采用的是一種分代(gene

5、rational )回收策略,用較高的頻率對年輕的對象(young generation進(jìn)行掃描和回收,這種叫做minor collection,而對老對象(old generation的檢查回收頻率要低很多,稱為major collection。這樣就不需要每次GC都將內(nèi)存中所有對象都檢查一遍,這種策略有利于實時觀察和回收。(Sun JVM 1.3 有兩種最基本的內(nèi)存收集方式:一種稱為copying或scavenge,將所有仍然生存的對象搬到另外一塊內(nèi)存后,整塊內(nèi)存就可回收。這種方法有效率, 但需要有一定的空閑內(nèi)存,拷貝也有開銷。這種方法用于minor collection。另外一種稱為ma

6、rk-compact,將活著的對象標(biāo)記出來,然后搬遷到一起連成大塊的內(nèi)存,其他內(nèi)存就可以回收了。這種方法不 需要占用額外的空間,但速度相對慢一些。這種方法用于major collection. )一些對象被創(chuàng)建出來只是擁有短暫的生命周期,比如 iterators 和本地變量。另外一些對象被創(chuàng)建是擁有很長的生命周期,比如 高持久化對象等。垃圾回收器的分代策略是把內(nèi)存區(qū)劃分為幾個代,然后為每個代分配一到多個內(nèi)存區(qū)塊。當(dāng)其中一個代用完了分配給他的內(nèi)存后,JVM會在分配的內(nèi)存區(qū)內(nèi) 執(zhí)行一個局部的GC(也可以叫minor collection)操作,為了回收處于“dead”狀態(tài)的對象所占用的內(nèi)存。局部G

7、C通常要不Full GC要快很多。JVM定義了兩個代,年輕代(yong generation)(有時稱為“nursery”托兒所)和老年代(old generation。年輕代包括 “Eden space(伊甸園)”和兩個“survivor spaces”。 虛擬內(nèi)存初始化的時候會把所有對象都分配到 Eden space,并且大部分對象也會在該區(qū)域被釋放。 當(dāng)進(jìn)行  minor GC的時候,VM會把剩下的沒有釋放的對象從Eden space移動到其中一個survivor spaces當(dāng)中。 此外,VM也會把那些長期存活在survivor spaces 里的對象移動到 老生代的“ten

8、ured” space中。當(dāng) tenured generation 被填滿后,就會產(chǎn)生Full GC,F(xiàn)ull GC會相對比較慢因為回收的內(nèi)容包括了所有的 live狀態(tài)的對象。pemanet generation這個代包括了所有java虛擬機(jī)自身使用的相對比較穩(wěn)定的數(shù)據(jù)對象,比如類和對象方法等。關(guān)于代的劃分,可以從下圖中獲得一個概況:如果垃圾回收器影響了系統(tǒng)的性能,或者成為系統(tǒng)的瓶頸,你可以通過自定義各個代的大小來優(yōu)化它的性能。使用JConsole,可以方便的查看到當(dāng)前應(yīng)用所配置的垃圾回收器的各個參數(shù)。想要獲得更詳細(xì)的參數(shù),可以參考以下調(diào)優(yōu)介紹:Tuning Garbage collectio

9、n with the 5.0 HotSpot VM最后,總結(jié)一下各區(qū)內(nèi)存:Eden Space (heap: 內(nèi)存最初從這個線程池分配給大部分對象。Survivor Space (heap:用于保存在eden space內(nèi)存池中經(jīng)過垃圾回收后沒有被回收的對象。Tenured Generation (heap:用于保持已經(jīng)在 survivor space內(nèi)存池中存在了一段時間的對象。Permanent Generation (non-heap: 保存虛擬機(jī)自己的靜態(tài)(refective數(shù)據(jù),例如類(class)和方法(method)對象。Java虛擬機(jī)共享這些類數(shù)據(jù)。這個區(qū)域被分割為只讀的和只寫

10、的,Code Cache (non-heap:HotSpot Java虛擬機(jī)包括一個用于編譯和保存本地代碼(native code)的內(nèi)存,叫做“代碼緩存區(qū)”(code cache)第三部分 監(jiān)控(工具發(fā)現(xiàn)問題)談到內(nèi)存監(jiān)控工具,JConsole是必須要介紹的,它是一個用JAVA寫的GUI程序,用來監(jiān)控VM,并可監(jiān)控遠(yuǎn)程的VM,易用且功能強(qiáng)大。具體 可監(jiān)控JAVA內(nèi)存、JAVA CPU使用率、線程執(zhí)行情況、加載類概況等,Jconsole需要在JVM參數(shù)中配置端口才能使用。由于是GUI程序,界面可視化,這里就不做詳細(xì)介紹,具體幫助支持文檔請參閱性能測試JConsole使用方法總結(jié):性能測試輔助工

11、具JConsole的使用方法.aspx或者參考SUN官網(wǎng)的技術(shù)文檔:在實際測試某一個項目時,內(nèi)存出現(xiàn)泄露現(xiàn)象。起初在性能測試的1個小時中,并不明顯,而在穩(wěn)定性測試的時候才發(fā)現(xiàn),應(yīng)用的HSF調(diào)用在經(jīng)過幾個小時 運(yùn)行后,就出現(xiàn)性能明顯下降的情況。在服務(wù)日志中報大量HSF超時,但所調(diào)用系統(tǒng)沒有任何超時日志,并且壓力應(yīng)用的load都很低。經(jīng)過查看日志后,認(rèn)為 應(yīng)用可能存在內(nèi)存泄漏。通過jconsole 以及 jmap 工具進(jìn)行分析發(fā)現(xiàn),確實存在內(nèi)存泄漏問題,其中PS Old Gen最終達(dá)到占用 100%的占用。如圖所示:從上圖可以看到,雖然每次Full GC,JVM內(nèi)存會有部分回收,但回收并不徹底,不可回收的內(nèi)存對象會越來越多,這樣便會出現(xiàn)以上的一個趨勢。在Full GC無法回收的對象越來越多時,最終已使用內(nèi)存達(dá)到系統(tǒng)分配的內(nèi)存最大值,系統(tǒng)最后無內(nèi)存可分配,最終down機(jī)。第四部分 分析調(diào)優(yōu)方法由于具體調(diào)優(yōu)方法涉及到應(yīng)用的配置信息,故在此暫不列出,可以參考性能測試小組發(fā)布的性能測試調(diào)優(yōu)寶典第四部分 總結(jié)內(nèi)存溢出主要是由于代碼編寫時對某些方法、類應(yīng)用不合理,或者沒有預(yù)估到臨

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論