JVM內存管理(轉)

轉載出處:http://blog.csdn.net/wind5shy/article/details/8349559

模型

JVM運行時數據區域

JVM執行Java程序的過程當中,會使用到各類數據區域,這些區域有各自的用途、建立和銷燬時間。根據《Java虛擬機規範(第二版)》(下文稱VM Spec)的規定,JVM包括下列幾個運行時數據區域:php

 

1.程序計數器(Program Counter Register):

每個Java線程都有一個程序計數器來用於保存程序執行到當前方法的哪個指令,對於非Native方法,這個區域記錄的是正在執行的VM原語的地址,若是正在執行的是Natvie方法,這個區域則爲空(undefined)。此內存區域是惟一一個在VM Spec中沒有規定任何OutOfMemoryError狀況的區域。java

2.Java虛擬機棧(Java Virtual Machine Stacks)

與程序計數器同樣,VM棧的生命週期也是與線程相同。VM棧描述的是Java方法調用的內存模型:每一個方法被執行的時候,都會同時建立一個幀(Frame)用於存儲本地變量表、操做棧、動態連接、方法出入口等信息。每個方法的調用至完成,就意味着一個幀在VM棧中的入棧至出棧的過程。mysql

常常有人把Java內存簡單的區分爲堆內存(Heap)和棧內存(Stack),實際中的區域遠比這種觀點複雜,這樣劃分只是說明與變量定義密切相關的內存區域是這兩塊。其中所指的「堆」後面會專門描述,而所指的「棧」就是VM棧中各個幀的本地變量表部分。本地變量表存放了編譯期可知的各類標量類型(boolean、byte、char、short、int、float、long、double)、對象引用(不是對象自己,僅僅是一個引用指針)、方法返回地址等。其中long和double會佔用2個本地變量空間(32bit),其他佔用1個。本地變量表在進入方法時進行分配,linux

當進入一個方法時,這個方法須要在幀中分配多大的本地變量是一件徹底肯定的事情,在方法運行期間不改變本地變量表的大小。程序員

在VM Spec中對這個區域規定了兩種異常情況:若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError異常;若是VM棧能夠動態擴展(VM Spec中容許固定長度的VM棧),當擴展時沒法申請到足夠內存則拋出OutOfMemoryError異常。算法

3.本地方法棧(Native Method Stacks)

本地方法棧與VM棧所發揮做用是相似的,只不過VM棧爲虛擬機運行VM原語服務,而本地方法棧是爲虛擬機使用到的Native方法服務。它的實現的語言、方式與結構並無強制規定,甚至有的虛擬機(譬如Sun Hotspot虛擬機)直接就把本地方法棧和VM棧合二爲一。和VM棧同樣,這個區域也會拋出StackOverflowError和OutOfMemoryError異常。sql

4.Java堆(Java Heap)

對於絕大多數應用來講,Java堆是虛擬機管理最大的一塊內存。Java堆是被全部線程共享的,在虛擬機啓動時建立。Java堆的惟一目的就是存放對象實例,絕大部分的對象實例都在這裏分配。apache

Java堆內還有更細緻的劃分:新生代、老年代,再細緻一點的:eden、from survivor、to survivor,甚至更細粒度的本地線程分配緩衝(TLAB)等,不管對Java堆如何劃分,目的都是爲了更好的回收內存,或者更快的分配內存。windows

根據VM Spec的要求,Java堆能夠處於物理上不連續的內存空間,它邏輯上是連續的便可,就像咱們的磁盤空間同樣。實現時能夠選擇實現成固定大小的,也能夠是可擴展的,不過當前全部商業的虛擬機都是按照可擴展來實現的(經過-Xmx和-Xms控制)。若是在堆中沒法分配內存,而且堆也沒法再擴展時,將會拋出OutOfMemoryError異常。api

5.方法區(Method Area)

叫「方法區」可能認識它的人還不太多,若是叫永久代(Permanent Generation)它的粉絲也許就多了。它還有個別名叫作Non-Heap(非堆)。

方法區中存放了每一個Class的結構信息,包括常量池、字段描述、方法描述等等。VM Space描述中對這個區域的限制很是寬鬆,除了和Java堆同樣不須要連續的內存,也能夠選擇固定大小或者可擴展外,甚至能夠選擇不實現垃圾收集。相對來講,垃圾收集行爲在這個區域是相對比較少發生的,但並非某些描述那樣永久代不會發生GC(至少對當前主流的商業JVM實現來講是如此),這裏的GC主要是對常量池的回收和對類的卸載,雖然回收的「成績」通常也比較差強人意,尤爲是類卸載,條件至關苛刻。

6.運行時常量池(Runtime Constant Pool)

Class文件中除了有類的版本、字段、方法、接口等描述等信息外,還有一項信息是常量表(constant_pool table),用於存放編譯期已可知的常量,這部份內容將在類加載後進入方法區(永久代)存放。可是Java語言並不要求常量必定只有編譯期預置入Class的常量表的內容才能進入方法區常量池,運行期間也可將新內容放入常量池(最典型的String.intern()方法)。

運行時常量池是方法區的一部分,天然受到方法區內存的限制,當常量池沒法在申請到內存時會拋出OutOfMemoryError異常。

7.本機直接內存(Direct Memory)

直接內存並非虛擬機運行時數據區的一部分,它根本就是本機內存而不是VM直接管理的區域。可是這部份內存也會致使OutOfMemoryError異常出現。

在JDK1.4中新加入了NIO類,引入一種基於渠道與緩衝區的I/O方式,它能夠經過本機Native函數庫直接分配本機內存,而後經過一個存儲在Java堆裏面的DirectByteBuffer對象做爲這塊內存的引用進行操做。這樣能在一些場景中顯著提升性能,由於避免了在Java對和本機堆中來回複製數據。

顯然本機直接內存的分配不會受到Java堆大小的限制,可是即然是內存那確定仍是要受到本機物理內存(包括SWAP區或者Windows虛擬內存)的限制的,通常服務器管理員配置JVM參數時,會根據實際內存設置-Xmx等參數信息,但常常忽略掉直接內存,使得各個內存區域總和大於物理內存限制(包括物理的和操做系統級的限制),而致使動態擴展時出現OutOfMemoryError異常。

 

Java堆

 

新生代(Young Generation)

大部分的對象的內存分配和回收在這裏完成。

Eden

新建的對象分配在此,新生代GC後被清空。

Survivor

存儲至少通過一次GC存活下來的對象,以增大該對象在提高至老生代前被回收的機會。

From Space

在新生代GC後被清空,GC後存活的對象放入老生代。

To Space

Eden中在新生代GC後存活的對象放在此。

老生代(Old Generation)

永生代(Permanent Generation)

垃圾回收

注意垃圾回收器Garbage Collector(簡稱Collector)和垃圾回收Garbage Collection(簡稱GC)的區別。

垃圾回收器Collector

Collector的職責

·          分配內存。

·          保證有引用的內存不被釋放。

·          回收沒有指針引用的內存。

 

對象被引用稱爲活對象,對象沒有被引用稱爲垃圾對象/垃圾/垃圾內存,找到垃圾對象並回收是Collector的一個主要工做,該過程稱爲GC。

 

好的Collector的特性

·          保證有引用的對象不被GC。

·          快速的回收內存垃圾。

·          在程序運行期間GC要高效,儘可能少的影響程序運行。和大部分的計算機問題同樣,這是一個關於空間,時間,效率平衡的問題。

·          避免內存碎片,內存碎片致使佔用大量內存的大對象內存申請難以知足。能夠採用Compaction技術避免內存碎片。Compaction技術:把活對象移向連續內存區的一端,回收其他的內存以便之後的分配。

·          良好的擴展性,內存分配和GC在多核機器上不該該成爲性能瓶頸。

設計或選擇Collector

·          串行或並行。

串行Collector在多核上也只有一個線程在運行,並行Collector能夠同時有多個線程執行GC,可是其算法更復雜。

·          併發或Stop the World。

Stop the World Collection執行GC時,須要凍住全部內存,所以更簡單一些,可是,在GC時,程序是被掛起的。併發GC時,程序和GC同時執行,固然,通常的併發GC算法仍是須要一些Stop the World時間。

·          Compacting or Non-compacting orCopying

Compacting: 去除內存碎片,回收內存慢,分配內存快。

Non-compacting: 容易產生內存碎片,回收內存快,分配內存慢,對大對象內存分配支持很差。

Copying: 複製活對象到新的內存區域,原有內存直接回收,須要額外的時間來作複製,額外的空間來作存儲。

GC性能指標

·          Throughput: 程序時間(不包含GC時間)/總時間。

·          GC overhead: GC時間/總時間。

·          Pause time: GC運行時程序掛起時間。

·          Frequency of GC: GC頻率。

·          Footprint: Size度量,如堆大小。

·          Promptness:對象變爲垃圾到該垃圾被回收後內存可用的時間。

分代GC

分代GC把內存劃分爲多個代(內存區域),每一個代存儲不一樣年齡的對象。常見的分爲2代,young和old。

分配內存時,先重新生代分配,若是新生代已滿,能夠執行GC(可能致使對象提高),若是有空間,則分配,若是新生代仍是沒有空間,能夠對整個內存堆GC。

新生代GC後還存活的對象能夠提高到老生代。

該機制基於如下觀察事實:

1.      大部分新分配的對象很快就沒有引用了,變成垃圾。

2.      不多有老生代對象引用新生代對象。

基於代內存存儲對象的特性,對不一樣代的內存可使用不一樣的GC算法。

新生代GC須要高效,快速,頻繁的執行,關注點主要在速度上。

老生代因爲增加緩慢,所以GC不頻繁,可是其內存空間比較大,所以,須要更長時間才能執行完GC。關注點在內存空間利用率上。

 

快速內存分配

大部分的內存分配請求發生時,Collector都有一塊大的連續內存塊,簡單的內存大小計算和指針移動就能夠分配內存了。所以很是快速。該技術稱爲bump-the-pointer技術。

 

對於多線程的內存分配,每一個線程使用Thread Local Allocation Buffer(TLAB)進行分配,所以仍是很高效。TLAB能夠看做一個線程的特殊代。只有TLAB滿的時候才須要進行同步操做。

 

GC根集合

GC運行時當前程序能夠直接訪問的對象。如線程中當前調用棧的方法參數,局部變量,靜態變量,當前線程對象等等。

Collector根據GC根集合來尋找全部活對象。GC根集合不可達對象天然就是垃圾了。

Serial Collector

單線程,Young and old GC是串行,stop the world GC的。

Young GC

Eden中活對象copy到to survivor中,大對象直接進老生代。

From survivor中相對老的活對象進入老生代,相對年輕的對象進入to survivor中。

若是to survivor放不下活對象,則這些活對象直接進入old。

經歷過young GC,Eden和from survivor都變成空的內存區域,to survivor存儲有活的對象。To survivor和from survivor角色互換。

Full (Old/Permanent) GC

Mark-sweep-compact算法。

S1 標識哪些對象是活的對象。

S2 標識哪些對象是垃圾。

S3 把活的對象壓縮到內存的一端,以即可以使用bump-the-pointer處理之後的內存分配請求。

 

非server-class machine 的默認GC。

Parallel Collector/Throughput Collector

利用了現代計算機大部分都是多核的事實。

Young GC

和Serial Collector同樣,是一個stop the world和copying Collector。只不過是多線程並行掃描和作copy,提升速度,減小了stop the world的時間,增大了throughput。

Full (Old/Permanent) GC

和serial collector同樣。Mark-sweep-compact算法。單線程。

Server-class machine的默認GC。

Parallel Compacting Collector

Young GC。

和Parallel Collector同樣。

Full (Old/Permanent) GC

Stop the world,而且多線程併發GC。

每一代被劃分爲一些長度固定的區域。

第1步(mark phase),GC根集合劃分後分發給多個GC線程,每一個GC線程更新可達活對象所在區域的信息(活對象的內存位置,大小)。

第2步(summary phase),操做在區域上,而不是對象上。因爲之前GC的影響,內存的一端活對象的密度比較高,在該階段找到一個臨界點,該臨界點之前的區域因爲活對象內存密度高,不參與GC,不作compact。該臨界點以後的區域參與GC,作compact。該階段爲單線程執行。

第3步(compact phase)。GC多線程使用summary info作回收和compact工做。

 

能夠設置GC線程數,防止GC線程長時間佔有整臺機器的資源。

-XX:ParallelGCThreads=n

Concurrent Mark Sweep Collector (CMS)

Young GC

和Parallel Collector同樣。

Full (Old/Permanent) GC

GC和程序併發執行。

Initial Phase:短暫停,標記GC根集合,單線程執行。

Concurrent marking phase: GC多線程標記從根集合可達的全部活對象,程序和GC併發運行。因爲是併發運行,有可能有活對象沒有被標記上。

concurrent pre-clean:單線程,併發執行。

Remark phase:短暫停,多線程標記在Concurrentmarking phase中有變化的相關對象。

Concurrent sweep phase:和程序併發執行,單線程執行,不作compacting。

concurrent reset:單線程,併發執行。

 

CMS不作compacting,不能使用bump-the-pointer技術,只能使用傳統的內存空閒鏈表技術。

致使內存分配變慢,影響了新生代的GC速度,由於Young的GC若是有對象提高的話依賴於Old的內存分配。

CMS須要更多的內存空間,由於markphase時程序仍是在運行,程序能夠申請更多的old空間。在mark phase中,CMS保證標識活對象,可是該過程當中,活對象可能轉變爲垃圾,只能等待下一次GC才能回收。

 

和其餘Collector不一樣,CMS不是等到old滿時才GC,基於之前的統計數據(GC時間,Old空間消耗速度)來決定什麼時候GC。CMS GC也能夠基於old空間的佔用率。

 

Incremental Mode。

CMS的concurrent phase能夠是漸進式執行。以減小程序的一次暫停時間。

 

4種Collector的對比和適用場景

直到jdk1.3.1,java只提供Serial Collector,Serial Collector在多核的機器上表現比較差。主要是throughput比較差。

大型應用(大內存,多核)應該選用並行Collector。

·          Serial Collector:大多數client-style機器。對於低程序暫停時間沒有需求的程序。

·          Parallel Collector:多核機器,對於低程序暫停時間沒有需求的程序。

·          Parallel Compacting Collector:多核機器,對於低程序暫停時間有需求的程序。

·          CMS Collector:和ParallelCompacting Collector相比,下降了程序暫停時間,可是young GC程序暫停時間變長,須要更大的堆空間,下降了程序的throughput。

 

優化

堆內存與GC

自動優化Ergonomics

J2SE 5.0後,Collector的選擇,堆大小的選擇,VM(client仍是server)的選擇,均可以依賴平臺和OS來作自動選擇。

JVM會自動選擇使用server mode仍是client mode。可是咱們同樣能夠手工設置。t

 

Server-class machine的選擇:

2個或更多的處理器 

And

2G或更多的物理內存

And

不是32bits,windows OS。

 

Client-class

The client JVM

The serial collector

Initial heap size = 4M

Max heap size=64M

 

Server-class

The server JVM

The parallel collector

Initial heap size= 1/64物理內存(>=32M),最大1G。

Max heap size=1/4物理內存,最大1G。

基於行爲的調優

能夠基於最大暫停時間或throughput。

·          -XX:MaxGCPauseMillis=n

指示vm調整堆大小和其餘參數來知足這個時間需求。若是vm不知足該目標,則減少堆大小來知足該目標。該目標沒有默認值。

·          -XX:GCTimeRatio=n

GC time/APP time=1/(1+n)

如n=99表示GC時間佔整個運行時間的1%。

若是該目標不能知足,則增大堆大小來知足該目標。默認值n=99。

·          Footprint Goal

若是最大暫停時間和Throughput目標都知足了,則減小堆大小直到有一個目標不知足,而後又回調。

 

目標優先級:

最大暫停時間>Throughput>footprint。

 

手動調優

因爲有了Ergonomics,第一個建議就是不要手工去配置各類參數。讓系統本身去根據平臺和OS來選擇。而後觀測性能,若是OK的話,不用搞了。可是Ergonomics也不是萬能的。所以仍是須要程序員來手工搞。注意性能問題必定要測量/調優/測量/調優不停的循環下去。

 

Vm mode 選擇

·          Java –server:server mode.

·          Java –client:client mode.

 

觀測性能主要使用gc的統計信息

·          -XX:+PrintGC:輸出GC信息。

·          -XX:+PrintGCDetail:輸出GC詳細信息。

·          -XX:+PrintGCTimeStamps:輸出時間戳,和–XX:+PrintGC或–XX:+PrintGCDetails一塊兒使用。

·          -Xloggc::gc.log 輸出到指定文件。

1 決定堆內存大小

決定整個堆內存的大小。內存的大小對於Collector的性能影響是最大的。

能夠決定堆空間的起始值和最大值,大型程序能夠考慮把起始值調大,避免程序啓動時頻繁GC和內存擴展申請,可能的話最好將最小值和最大值設成一致。

堆空間中可用內存的比例範圍,vm會動態管理堆內存來知足該比例範圍。

·          -Xms:初始堆大小,默認爲物理內存的1/64(<1GB);默認(MinHeapFreeRatio參數能夠調整)空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制。

·          -Xmx:最大堆大小,默認(MaxHeapFreeRatio參數能夠調整)空餘堆內存大於70%時,JVM會減小堆直到 -Xms的最小限制。

·          -XX:MinHeapFreeRatio=n

·          -XX:MaxHeapFreeRatio=n

2 決定代空間大小

新生代空間越大,則新生代(minor)GC的頻率越小。可是,給定堆內存大小,新生代空間大,則full/major GC頻率變大。

若是沒有過多的Full GC或者過長的暫停時間問題,給新生代儘可能大的空間。

 

YoungGeneration Guarantee

對於serial collector,當執行新生代 GC時,必須保證老生代中有可用的空間來處理最壞狀況(即eden和survivor空間中的對象都是活對象,須要提高至老生代),若是不知足,則該新生代GC觸發full GC。因此對於serial collector,設置eden+survivor的內存不要大過老生代內存。

其餘collector不作該保證,只有老生代沒法存儲提高對象時才觸發full GC。

 

對於其餘collector,因爲多線程作新生代 GC時,考慮到最壞狀況,每一個線程要在老生代內存預留必定空間作對象提高,所以可能致使內存碎片。所以老生代內存應該調整的更大一些。

·          -Xmn:新生代的內存空間大小,在保證堆大小不變的狀況下,增大新生代後,將會減少老生代大小。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8。

·          -XX:NewSize=n:新生代初始大小。

·          -XX:MaxNewSize=n:新生代上限。

·          -XX:NewRatio=n:新生代和老生代的比例。

·          -XX:SurvivorRatio=n:新生代中Eden區域與Survivor區域的容量比值,默認值爲8。兩個Survivor區與一個Eden區的比值爲2:8,一個Survivor區佔整個年輕代的1/10。

·          -XX:PermSize=n:永生代初始大小,默認值爲物理內存的1/64。

·          -XX:MaxPermSize=n:永生代上限,默認值爲物理內存的1/4。

3.決定使用Collector

Collector選擇

·          -XX:+UseSerialGC Serial

·          -XX:+UseParallelGC Parallel

·          -XX:+UseParallelOldGC Parallel compacting

·          -XX:+UseConcMarkSweepGC Concurrent mark–sweep (CMS)

 

Parallel和Parallel Compacting Collector

·          -XX:ParallelGCThreads=n:並行收集器的線程數。

·          -XX:MaxGCPauseMillis=n

·          -XX:GCTimeRatio=n

設定目標好於明確設定參數值。

 

爲了增大Throughput,堆大小須要變大。能夠把堆大小設爲物理內存容許的最大值(同時程序不swapping)來檢測該環境能夠支持的最大throughput。

爲了減少最大暫停時間和footprint,堆大小須要變小。

2個目標有必定的矛盾,所以要視具體應用場景,作平衡。

 

CMSCollector

·          -XX:+CMSIncrementalMode:啓動增量模式

·          -XX:+CMSIncrementalPacing:依據收集的統計信息啓用增量模式自動調節佔空比

·          -XX:ParallelGCThreads=n

·          -XX:CMSInitiatingOccupancyFraction=n:默認68。

·          -XX:+UseCMSInitiatingOccupancyOnly:使vm只使用old內存佔用比來觸發CMSGC。

非堆內存

·          -Xss :設置每一個線程的堆棧大小。JDK5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K。更具應用的線程所需內存大小進行調整。在相同物理內存下,減少這個值能生成更多的線程。可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成。

·          -XX:MaxDirectMemorySize:本機直接內存大小上限,默認和堆(-Xmx)內存上限一致。

 

檢測

java工具

freeMemory(),totalMemory(),maxMemory()

java.lang.Runtime類中的freeMemory(), totalMemory(), maxMemory()這幾個方法的反映的都是 java這個進程的內存狀況,跟操做系統的內存根本沒有關係。

 

maxMemory()這個方法返回的是java虛擬機(這個進程)能構從操做系統那裏挖到的最大的內存,以字節爲單位,若是在運行java程序的時候,沒有添加-Xmx參數,那麼就是jvm默認的可使用內存大小,client爲64M,server爲1G。若是添加了-Xmx參數,將以這個參數後面的值爲準。

 

totalMemory()這個方法返回的是java虛擬機如今已經從操做系統那裏挖過來的內存大小,也就是java虛擬機這個進程當時所佔用的全部內存。若是在運行java的時候沒有添加-Xms參數,那麼,在java程序運行的過程的,內存老是慢慢的從操做系統那裏挖的,基本上是用多少挖多少,直到挖到maxMemory()爲止,因此totalMemory()是慢慢增大的。若是用了-Xms參數,程序在啓動的時候就會無條件的從操做系統中挖 -Xms後面定義的內存數,而後在這些內存用的差很少的時候,再去挖。

 

freeMemory()是什麼呢,剛纔講到若是在運行java的時候沒有添加-Xms參數,那麼,在java程序運行的過程的,內存老是慢慢的從操 做系統那裏挖的,基本上是用多少挖多少,可是java虛擬機100%的狀況下是會稍微多挖一點的,這些挖過來而又沒有用上的內存,實際上就是 freeMemory(),因此freeMemory()的值通常狀況下都是很小的,可是若是你在運行java程序的時候使用了-Xms,這個時候由於程序在啓動的時候就會無條件的從操做系統中挖-Xms後面定義的內存數,這個時候,挖過來的內存可能大部分沒用上,因此這個時候freeMemory()可能會有些大。

jstack

若是java程序崩潰生成core文件,jstack工具能夠用來得到core文件的java stack和native stack的信息,從而能夠輕鬆地知道java程序是如何崩潰和在程序何處發生問題。另外,jstack工具還能夠附屬到正在運行的java程序中,看到當時運行的java程序的java stack和native stack的信息, 若是如今運行的java程序呈現hung的狀態,jstack是很是有用的。目前只有在Solaris和Linux的JDK版本里面纔有。

 

例子:

jstack 6448

 

jconsole

jconsole是基於Java ManagementExtensions (JMX)的實時圖形化監測工具,這個工具利用了內建到JVM裏面的JMX指令來提供實時的性能和資源的監控,包括了Java程序的內存使用,Heap size, 線程的狀態,類的分配狀態和空間使用等等。

jinfo

jinfo能夠從core文件或進程中得到Java應用程序的配置信息,目前只有在Solaris和Linux的JDK版本里面纔有。

jmap

jmap 能夠從core文件或進程中得到jvm的相關內存信息,包括Heapsize, Perm size等等,目前只有在Solaris和Linux的JDK版本里面纔有。

參數以下:

·          -heap:打印jvm heap的狀況

·          -histo:打印jvm heap的直方圖。其輸出信息包括類名,對象數量,對象佔用大小。

·          -histo:live :同上,可是隻答應存活對象的狀況

·          -permstat:打印permanentgeneration heap狀況

 

例子:

jmap -heap 2083

 

jmap -histo 2083 | jmap-histo:live 2083

jstat

利用了JVM內建的指令對Java應用程序的資源和性能進行實時的命令行的監控,包括了對Heap size和垃圾回收情況的監控等等。

具體參數以下:

·          -class:統計classloader行爲信息

·          -compile:統計編譯行爲信息

·          -gc:統計jdk gc時heap信息

·          -gccapacity:統計不一樣的generations(不知道怎麼翻譯好,包括新生區,老年區,permanent區)相應的heap容量狀況

·          -gccause:統計gc的狀況,(同-gcutil)和引發gc的事件

·          -gcnew:統計gc時,新生代的狀況

·          -gcnewcapacity:統計gc時,新生代heap容量

·          -gcold:統計gc時,老年區的狀況

·          -gcoldcapacity:統計gc時,老年區heap容量

·          -gcpermcapacity:統計gc時,permanent區heap容量

·          -gcutil:統計gc時,heap狀況

通常比較經常使用的幾個參數是:

jstat -class 2083 1000 10 (每隔1秒監控一次,一共作10次)

輸出內容含義以下:

 

Loaded     Numberof classes loaded.

Bytes        Numberof Kbytes loaded.

Unloaded Numberof classes unloaded.

Bytes        Numberof Kbytes unloaded.

Time         Timespent performing class load and unload operations.

 

jstat -gc 2083 2000 20(每隔2秒監控一次,共作10)

輸出內容含義以下:

 

S0C  Currentsurvivor space 0 capacity (KB).

EC    Currenteden space capacity (KB).

EU    Edenspace utilization (KB).

OC    Currentold space capacity (KB).

OU   Oldspace utilization (KB).

PC    Currentpermanent space capacity (KB).

PU    Permanentspace utilization (KB).

YGC Numberof young generation GC Events.

YGCT        Younggeneration garbage collection time.

FGC  Numberof full GC events.

FGCT         Fullgarbage collection time.

GCT Totalgarbage collection time.

 

linux命令

top

TOP是一個動態顯示過程,便可以經過用戶按鍵來不斷刷新當前狀態.若是在前臺執行該命令,它將獨佔前臺,直到用戶終止該程序爲止.比較準確的說,top命令提供了實時的對系統處理器的狀態監視.它將顯示系統中CPU最「敏感」的任務列表.該命令能夠按CPU使用.內存使用和執行時間對任務進行排序;並且該命令的不少特性均可以經過交互式命令或者在我的定製文件中進行設定.

top - 12:38:33 up 50 days, 23:15,  7 users, load average: 60.58, 61.14, 61.22

Tasks: 203 total,  60 running, 139 sleeping,   4 stopped,  0 zombie

Cpu(s) : 27.0%us, 73.0%sy,  0.0%ni,  0.0%id, 0.0%wa,  0.0%hi,  0.0%si, 0.0%st

Mem:  1939780k total,  1375280kused,   564500k free,   109680k buffers

Swap: 4401800k total,   497456kused,  3904344k free,   848712k cached

PID USER      PR NI  VIRT  RES SHR S %CPU %MEM    TIME+  COMMAND                               

 4338oracle    25   0 627m 209m 207m R    0 11.0297:14.76 oracle                               

 4267oracle    25   0 626m 144m 143m R    6  7.6 89:16.62 oracle                               

 3458oracle    25   0 672m 133m 124m R    0  7.1  1283:08 oracle                               

 3478oracle    25   0 672m 124m 115m R    0  6.6  1272:30 oracle                               

 3395oracle    25   0 672m 122m 113m R    0  6.5  1270:03 oracle                                

 3480oracle    25   0 672m 122m 109m R    8  6.4  1274:13 oracle                               

 3399oracle    25   0 672m 121m 110m R    0  6.4  1279:37 oracle                               

 4261oracle    25   0 634m 100m  99m R    0 5.3  86:13.90 oracle                               

25737 oracle    25  0  632m  81m 74m R    0  4.3 272:35.42 oracle                               

 7072oracle    25   0 626m  72m  71m R   0  3.8   6:35.68 oracle                               

16073 oracle    25  0  630m  68m 63m R    8  3.6 175:20.36 oracle                               

16140 oracle    25  0  630m  66m 60m R    0  3.5 175:13.42 oracle                               

16122 oracle    25  0  630m  66m 60m R    0  3.5 176:47.73 oracle                               

  786oracle    25   0 627m  63m  63m R   0  3.4   1:54.93 oracle                               

 4271oracle    25   0 627m  59m  58m R   8  3.1  86:09.64 oracle                               

 4273oracle    25   0 627m  57m  56m R   8  3.0  84:38.20 oracle                                

22670 oracle    25  0  626m  50m 49m R    0  2.7 84:55.82 oracle    

 

統計信息區前五行是系統總體的統計信息。

 

1. 第一行是任務隊列信息

12:38:33

當前時間

up 50days

系統運行時間,格式爲時:分

1 user

當前登陸用戶數

load average: 0.06, 0.60, 0.48

系統負載,即任務隊列的平均長度。 三個數值分別爲  1分鐘、5分鐘、15分鐘前到如今的平均值。

 

2. 第2、三行爲進程和CPU的信息

當有多個CPU時,這些內容可能會超過兩行。

Tasks: 29 total

進程總數

1 running

正在運行的進程數

28 sleeping

睡眠的進程數

0 stopped

中止的進程數

0 zombie

殭屍進程數

Cpu(s): 0.3% us

用戶空間佔用CPU百分比

1.0% sy

內核空間佔用CPU百分比

0.0% ni

用戶進程空間內改變過優先級的進程佔用CPU百分比

98.7% id

空閒CPU百分比

0.0% wa

等待輸入輸出的CPU時間百分比

0.0% hi

0.0% si

 

3. 第四五行爲內存信息。

Mem: 191272k total

物理內存總量

173656k used

使用的物理內存總量

17616k free

空閒內存總量

22052k buffers

用做內核緩存的內存量

Swap: 192772k total

交換區總量

0k used

使用的交換區總量

192772k free

空閒交換區總量

123988k cached

緩衝的交換區總量。 內存中的內容被換出到交換區,然後又被換入到內存,但使用過的交換區還沒有被覆蓋, 該數值即爲這些內容已存在於內存中的交換區的大小。相應的內存再次被換出時可沒必要再對交換區寫入。

 

進程信息

列名

含義

PID

進程id

PPID

父進程id

RUSER

Real user name

UID

進程全部者的用戶id

USER

進程全部者的用戶名

GROUP

進程全部者的組名

TTY

啓動進程的終端名。不是從終端啓動的進程則顯示爲 ?

PR

優先級

NI

nice值。負值表示高優先級,正值表示低優先級

P

最後使用的CPU,僅在多CPU環境下有意義

%CPU

上次更新到如今的CPU時間佔用百分比

TIME

進程使用的CPU時間總計,單位秒

TIME+

進程使用的CPU時間總計,單位1/100秒

%MEM

進程使用的物理內存百分比

VIRT

進程使用的虛擬內存總量,單位kb。VIRT=SWAP+RES

SWAP

進程使用的虛擬內存中,被換出的大小,單位kb。

RES

進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA

CODE

可執行代碼佔用的物理內存大小,單位kb

DATA

可執行代碼之外的部分(數據段+棧)佔用的物理內存大小,單位kb

SHR

共享內存大小,單位kb

nFLT

頁面錯誤次數

nDRT

最後一次寫入到如今,被修改過的頁面數。

S

進程狀態。
            D=不可中斷的睡眠狀態
            R=運行
            S=睡眠
            T=跟蹤/中止
            Z=殭屍進程

COMMAND

命令名/命令行

WCHAN

若該進程在睡眠,則顯示睡眠中的系統函數名

Flags

任務標誌,參考 sched.h

 

pmap

[root@CentOS5 ~]#pmap -d 9639

9639:  /usr/local/apache2/bin/httpd -k start

 

Address  Kbytes Mode  Offset           Device    Mapping

00110000      28 r-x-- 0000000000000000 008:00003librt-2.5.so

00117000       4 r---- 0000000000006000 008:00003librt-2.5.so

00118000       4 rw--- 0000000000007000 008:00003librt-2.5.so

00119000   1276 r-x-- 0000000000000000 008:00003 libc-2.5.so

00258000       8 r---- 000000000013f000 008:00003libc-2.5.so

0025a000       4 rw--- 0000000000141000 008:00003libc-2.5.so

0025b000      12 rw--- 000000000025b000 000:00000   [ anon ]

0025e000      60 r-x-- 0000000000000000 008:00003libexslt.so.0.8.12

0026d000       4 rw--- 000000000000e000 008:00003libexslt.so.0.8.12

0026e000    268 r-x-- 0000000000000000 008:00003 libmysqlclient.so.16.0.0

002b1000    168 rw--- 0000000000042000 008:00003 libmysqlclient.so.16.0.0

002db000       4 rw--- 00000000002db000 000:00000   [ anon ]

002dc000    448 r-x-- 0000000000000000 008:00003 libfreetype.so.6.4.0

0034c000      16 rw--- 000000000006f000 008:00003libfreetype.so.6.4.0

00350000      72 r-x-- 0000000000000000 008:00003libz.so.1.2.3

00362000       4 rw--- 0000000000011000 008:00003libz.so.1.2.3

00363000      60 r-x-- 0000000000000000 008:00003libresolv-2.5.so

00372000       4 r---- 000000000000e000 008:00003libresolv-2.5.so

00373000       4 rw--- 000000000000f000 008:00003libresolv-2.5.so

00374000       8 rw--- 0000000000374000 000:00000   [ anon ]

00376000      76 r-x-- 0000000000000000 008:00003libnsl-2.5.so

00389000       4 r---- 0000000000012000 008:00003libnsl-2.5.so

0038a000       4 rw--- 0000000000013000 008:00003libnsl-2.5.so

0038b000       8 rw--- 000000000038b000 000:00000   [ anon ]

0038d000    200 r-x-- 0000000000000000 008:00003 libcurl.so.3.0.0

003bf000       4 rw--- 0000000000031000 008:00003libcurl.so.3.0.0

003c0000    192 r-x-- 0000000000000000 008:00003 libidn.so.11.5.19

003f0000       4 rw--- 000000000002f000 008:00003libidn.so.11.5.19

003f1000     188 r-x-- 0000000000000000 008:00003libxslt.so.1.1.15

00420000       4 rw--- 000000000002f000 008:00003libxslt.so.1.1.15

00421000    588 r-x-- 0000000000000000 008:00003 libkrb5.so.3.3

004b4000      12 rw--- 0000000000092000 008:00003libkrb5.so.3.3

004b7000       8 r-x-- 0000000000000000 008:00003libcom_err.so.2.1

004b9000       4 rw--- 0000000000001000 008:00003libcom_err.so.2.1

004ba000    148 r-x-- 0000000000000000 008:00003 libk5crypto.so.3.1

004df000       4 rw--- 0000000000025000 008:00003libk5crypto.so.3.1

004e0000       8 r-x-- 0000000000000000 008:00003libkeyutils-1.2.so

004e2000       4 rw--- 0000000000001000 008:00003libkeyutils-1.2.so

004e3000      36 r-x-- 0000000000000000 008:00003libnss_files-2.5.so

004ec000       4 r---- 0000000000008000 008:00003libnss_files-2.5.so

004ed000       4 rw--- 0000000000009000 008:00003libnss_files-2.5.so

004f4000    124 r-x-- 0000000000000000 008:00003 libexpat.so.0.5.0

00513000       8 rw--- 000000000001e000 008:00003libexpat.so.0.5.0

00517000    180 r-x-- 0000000000000000 008:00003 libgssapi_krb5.so.2.2

00544000       4 rw--- 000000000002d000 008:00003libgssapi_krb5.so.2.2

00545000      32 r-x-- 0000000000000000 008:00003libkrb5support.so.0.1

0054d000       4 rw--- 0000000000007000 008:00003libkrb5support.so.0.1

0054e000      88 r-x-- 0000000000000000 008:00003libselinux.so.1

00564000       8 rw--- 0000000000015000 008:00003libselinux.so.1

00566000      44 r-x-- 0000000000000000 008:00003memcache.so

00571000       4 rw--- 000000000000a000 008:00003memcache.so

00572000      28 r-x-- 0000000000000000 008:00003mcrypt.so

00579000       4 rw--- 0000000000007000 008:00003mcrypt.so

0057a000    156 r-x-- 0000000000000000 008:00003 libmcrypt.so.4.4.8

005a1000      12 rw--- 0000000000027000 008:00003libmcrypt.so.4.4.8

005a4000      20 rw--- 00000000005a4000 000:00000   [ anon ]

005c9000    120 r-x-- 0000000000000000 008:00003 libjpeg.so.62.0.0

005e7000       4 rw--- 000000000001d000 008:00003libjpeg.so.62.0.0

00605000      88 r-x-- 0000000000000000 008:00003mysqli.so

0061b000       8 rw--- 0000000000016000 008:00003mysqli.so

0068a000    236 r-x-- 0000000000000000 008:00003 libgd.so.2.0.0

006c5000    128 rw--- 000000000003a000 008:00003 libgd.so.2.0.0

006e5000      16 rw--- 00000000006e5000 000:00000   [ anon ]

007bf000    104 r-x-- 0000000000000000 008:00003 ld-2.5.so

007d9000       4 r---- 0000000000019000 008:00003ld-2.5.so

007da000       4 rw--- 000000000001a000 008:00003ld-2.5.so

00816000       4 r-x-- 0000000000816000 000:00000   [ anon ]

00817000    988 r-x-- 0000000000000000 008:00003 libxml2.so.2.6.19

0090e000      32 rw--- 00000000000f7000 008:00003libxml2.so.2.6.19

00916000       4 rw--- 0000000000916000 000:00000   [ anon ]

00929000       8 r-x-- 0000000000000000 008:00003libdl-2.5.so

0092b000       4 r---- 0000000000001000 008:00003libdl-2.5.so

0092c000       4 rw--- 0000000000002000 008:00003libdl-2.5.so

0092f000      76 r-x-- 0000000000000000 008:00003libpthread-2.5.so

00942000       4 r---- 0000000000013000 008:00003libpthread-2.5.so

00943000       4 rw--- 0000000000014000 008:00003libpthread-2.5.so

00944000       8 rw--- 0000000000944000 000:00000   [ anon ]

00948000    148 r-x-- 0000000000000000 008:00003 libm-2.5.so

0096d000       4 r---- 0000000000024000 008:00003libm-2.5.so

0096e000       4 rw--- 0000000000025000 008:00003libm-2.5.so

00971000      12 r-x-- 0000000000000000 008:00003libuuid.so.1.2

00974000       4 rw--- 0000000000003000 008:00003libuuid.so.1.2

0097b000    152 r-x-- 0000000000000000 008:00003 libapr-1.so.0.4.2

009a1000       4 rw--- 0000000000025000 008:00003libapr-1.so.0.4.2

009ab000    236 r-x-- 0000000000000000 008:00003 libsepol.so.1

009e6000       4 rw--- 000000000003b000 008:00003libsepol.so.1

009e7000      40 rw--- 00000000009e7000 000:00000   [ anon ]

00a2f000      20 r-x-- 0000000000000000 008:00003pdo_mysql.so

00a34000       4 rw--- 0000000000005000 008:00003pdo_mysql.so

00aa1000      36 r-x-- 0000000000000000 008:00003libcrypt-2.5.so

00aaa000       4 r---- 0000000000008000 008:00003libcrypt-2.5.so

00aab000       4 rw--- 0000000000009000 008:00003libcrypt-2.5.so

00aac000    156 rw--- 0000000000aac000 000:00000  [ anon ]

00b78000    108 r-x-- 0000000000000000 008:00003 libaprutil-1.so.0.3.9

00b93000       4rw--- 000000000001b000 008:00003 libaprutil-1.so.0.3.9

00b94000   6560 r-x-- 0000000000000000 008:00003 libphp5.so

011fc000    156 rw--- 0000000000667000 008:00003 libphp5.so

01223000      20 rw--- 0000000001223000 000:00000   [ anon ]

03492000    268 r-x-- 0000000000000000 008:00003 libssl.so.0.9.8e

034d5000      16 rw--- 0000000000042000 008:00003libssl.so.0.9.8e

03c71000      12 r-x-- 0000000000000000 008:00003libgpg-error.so.0.3.0

03c74000       4 rw--- 0000000000002000 008:00003libgpg-error.so.0.3.0

03c77000    504 r-x-- 0000000000000000 008:00003 libgcrypt.so.11.5.2

03cf5000      12 rw--- 000000000007d000 008:00003libgcrypt.so.11.5.2

05748000   1192 r-x-- 0000000000000000 008:00003 libcrypto.so.0.9.8e

05872000      76 rw--- 0000000000129000 008:00003libcrypto.so.0.9.8e

05885000      16 rw--- 0000000005885000 000:00000   [ anon ]

08048000    484 r-x-- 0000000000000000 008:00003 httpd

080c1000      12 rw--- 0000000000078000 008:00003 httpd

080c4000      12 rw--- 00000000080c4000 000:00000   [ anon ]

0951b000   2136 rw--- 000000000951b000 000:00000  [ anon ]

b7cb2000   2048 r---- 0000000000000000 008:00003 locale-archive (deleted)

b7ee3000      64 rw-s- 0000000000000000 000:00009 zero(deleted)

b7ef3000      12 rw--- 00000000b7ef3000 000:00000   [ anon ]

b7f01000       4 r---- 00000000005da000 008:00003locale-archive (deleted)

b7f02000       4 rw--- 00000000b7f02000 000:00000   [ anon ]

bfd31000      84 rw--- 00000000bffea000 000:00000   [ stack ]

mapped: 21164K    writeable/private: 3340K    shared: 64K

 

每列的含義以下:

Address:進程所佔的地址空間

Kbytes:該虛擬段的大小

RSS:設備號(主設備:次設備)

Anon:設備的節點號,0表示沒有節點與內存相對應

Locked:是否容許swapped

Mode 權限:r=read, w=write,x=execute, s=shared, p=private(copy on write)

Mapping:bash 對應的映像文件名

 

Resident :表示在內存中駐留的段的空間  

shared :表示這些被分配的內存是被系統中其餘進程共享的。   

private :表示只能被該進程使用的空間大小。你能夠發現share的空間不具備 private的屬性。

 

參考連接:

http://hllvm.group.iteye.com/group/wiki/2857-JVM

http://www.iteye.com/topic/976522

http://blog.csdn.net/kelly859/article/details/5827365

http://blog.csdn.net/sanshiqiduer/article/details/1933625

相關文章
相關標籤/搜索