多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 自動內存管理機制

自動內存管理機制

來源:程序員人生   發布時間:2016-06-29 18:06:54 閱讀次數:2989次

1:Java內存區域與內存溢出異常

       在運行Java程序時,Java虛擬機會把管理的內存劃分為若干個不同的數據區域。

Java虛擬機運行時數據區

數據區域圖中,除方法區和堆區是線程同享區外,其他3個是線程隔離的數據區(private)

程序計數器(Program Counter Register):屬于線程私有的,占用的內存空間較少,可以看成是當前線程所履行字節碼的行號唆使器,字節碼解釋器工作時就是通過改變這個計數器的值來選擇下1條,需要履行的字節碼指令,分支,循環,跳轉,異常處理,線程恢復等基礎功能需要依賴這個計數器來完成,這個區域是jvm規范中沒有規定任何OutOfMemoryError情況區域。

虛擬機棧:和程序計數器1樣,都屬于線程私有,生命周期與線程相同,描寫的是java方法履行的內存模型,每一個方法履行都會創建1個棧幀,用于存儲局部變量表,操作棧,動態鏈接,方法出口等信息,每個方法被調用直至履行完成的進程,就對應1個棧幀在jvm stack 從入棧到出棧的進程.局部變量表寄存了編譯期可知的各種數據基本類型(Boolean,byte,char,short,int,float,long,double),和對象的援用。這個區域中定義了2種異常情況,如果線程要求的棧深度大于jvm所允許的深度,將拋出StackOverflowError異常,如果jvm可以動態擴大,當擴大沒法申請到足夠的內存空間是會拋出OutOfMemoryError異常。(這些數據區域異常將在下面的例子都講到)。

         本地方法棧:與虛擬機棧比較相似。其區分:虛擬機棧為虛擬機履行Java方法服務,而本地方法棧則為虛擬機使用Native方法服務。

         堆(Heap):jvm中內存占用最大的1塊,是所有線程同享的1塊內存區域.在jvm啟動時創建,寄存的是所有對象實例(或數組),所有的對象實例都在這里進行動態分配,當類空間沒法再擴大會拋出OutOfMemoryError異常。Java堆是垃圾搜集器管理的主要區域,而搜集器采取分代搜集算法。

         方法區(Method Area):與堆類似,也是各個線程同享的內存區域,主要用來存儲加載的類信息,常量,靜態變量,即時編譯器編譯后的代碼等數據,當方法區沒法滿足內存分配時,也拋出OutOfMemoryError異常。運行經常量池是方法區的1部份,用于寄存編譯期生成的各種字面量和符號援用相對Class文件常量池的重要特點是具有動態性(常量并不是強迫編譯期產生,運行期間也能夠新增,例如String類的intern()方法)。

         直接內存(DirectMemort):其實不屬于數據區,也不屬于java定義的內存區域。由于NIO(New Input/Output)類,引入了1種基于通道與緩沖區(Buffer)的I/O方式。

對象訪問

Object object = new Object(); 

Object object 這部份存儲在java棧的本地變量表中,作為1個援用(reference)類型存在。

new Object() 這部份存儲在java堆中,構成了1塊存儲了Object類型所有的實例數據值的結構化內存,動態變化,長度不固定。

方法區:在java堆中,必須要找到此對象類型數據,比如,對象類型,基類,實現的接口,方法等都寄存在方法區。

       對象訪問方式有兩種:句柄和直接指針。

              句柄:reference中存儲是對象的句柄地址,而句柄包括了對象實例數據和類型數據各自具體地址信息。好處:在對象移動時只需改變句柄中的實例數據指針,reference本身不需要修改。

              直接指針:reference中直接存儲的就是對象地址。好處:速度快,它節省了1次指針定位的時間開消。

實戰:OutOfMemoryError異常

1.      Java堆溢出

調劑虛擬機最小值(-Xms)和最大值(-Xmx),并通過參數-XX:+HeapDumpOnOutOfMemoryError生成快照。要解決這個區域的異常,通過內存映像分析工具對快照分析,確認內存中的對象是不是是必要的,分清楚出現了內存泄漏還是內存溢出。若是內存泄漏,通過工具查看泄漏對象到GCRoots援用鏈,找到泄漏對象是通過怎樣的路徑與GCRoots相干聯并致使垃圾搜集器沒法自動回收。若不存在泄漏,則檢查虛擬機堆參數與機器物理內存對照看是不是還能調大或從代碼上檢查某些對象生命周期是不是太長,嘗試減少程序運行期的內存消耗。

2.      虛擬機棧和本地方法棧溢出

調理棧容量大小(-Xss)。如果線程要求的棧深度大于虛擬機所允許的最大深度,將會拋出StackOverflowError異常。使用-Xss參數減小棧內存容量或增加此方法幀中本地變量表的程度都使棧深度縮小。

3.      運行經常量池溢出

調理參數-XX:PermSize和-XX:MaxPermSize限制方法區的大小,然后使用String.intern()這個Native方法向常量池中添加內容。運行經常量池溢出,在OutOfMemoryError后面跟隨提示信息是“PermGen space”,說明運行經常量池屬于方法區(HotSpot虛擬機的永久代)的1部份。

4.      方法區溢出

一樣使用參數-XX:PermSize和-XX:MaxPermSize限制方法區的大小,然后不斷產生大量的class來加載到內存,從而出現OutOfMemoryError。所以在常常動態生成大量Class的利用中,需要特別注意類的回收狀態。

5.      本機直接內存溢出

通過參數-XX:MaxDirectMemorySize指定DirectMemory容量,若不指定則與Java堆最大值1樣。可以直接通過反射獲得Unsafe實例并進行內存分配,使用unsafe.allocateMemory()申請分配內存。不足時會出現OutOfMemoryError。


2.垃圾搜集器與內存分配策略

概述

       Java內存運行時區域的各個部份,其中程序計數器、VM棧、本地方法棧3個區域隨線程而生,隨線程而滅;棧中的幀隨著方法進入、退出而有條不紊的進行著出棧入棧操作。而Java堆和方法區(包括運行經常量池)則不1樣,我們必須等到程序實際運行期間才能知道會創建哪些對象,這部份內存的分配和回收都是動態的。

判斷對象已死

       1)援用計數算法(對象中添加1個援用計數器,當有1個地方援用它,計數器加1,當援用失效,計數器減1,任什么時候刻計數器為0的對象就是不可能再被使用的),但援用計數算法沒法解決對象循環援用的問題。

       根搜索算法(通過1系列的稱為“GCRoots”的點作為起始進行向下搜索,當1個對象到GCRoots沒有任何援用鏈(ReferenceChain)相連,則證明此對象是不可用的),主流程序語言Java,c#都使用此算法。Java語言中,GC Roots包括:  

1.VM棧(幀中的本地變量)中的援用。
2.方法區中的靜態援用 和常量援用的對象。
3.JNI(即1般說的Native方法)中的援用。

2)生存還是死亡? 

       判定1個對象死亡,最少經歷兩次標記進程:如果對象在進行根搜索后,發現沒有與GC Roots相連接的援用鏈,那它將會被第1次標記,并在稍后履行他的finalize()方法(如果它有的話)。這里所謂的履行是指虛擬機會觸發這個方法,但其實不許諾會等待它運行結束。這點是必須的,否則1個對象在finalize()方法履行緩慢,乃至有死循環甚么的將會很容易致使全部系統崩潰。 finalize()方法是對象最后1次逃脫死逃亡運的機會,稍后GC將進行第2次范圍稍小的標記,如果在finalize()中對象成功解救自己(只要重新建立到GC Roots的連接便可,比方把自己賦值到某個援用上),那在第2次標記時它將被移除出行將回收的集合,如果對象這時候候還沒有逃脫,那基本上它就真的離死不遠了。 需要關閉外部資源之類的事情,基本上它能做的使用try-finally可以做的更好。      

3)回收方法區

       方法區即后文提到的永久代,很多人認為永久代是沒有GC的,這區GC性價比1般比較低:在堆中,特別是在新生代,進行1次GC可以1般可以回收70%~95%的空間,而永久代的GC效力遠小于此。但是目前方法區主要回收兩部份內容:廢棄常量與無用類。需要滿足下面3個條件:  
1.該類所有的實例都已被GC,也就是JVM中不存在該Class的任何實例。  
2.加載該類的ClassLoader已被GC  
3.該類對應的java.lang.Class對象沒有在任何地方被援用,如不能在任何地方通過反射訪問該類的方法。

垃圾搜集算法

1.標記-清除算法(Mark-Sweep

算法分成標記清除兩個階段,首先標記出所有需要回收的對象,然后回收所有需要回收的對象。主要缺點有兩個,1是效力問題,標記和清算兩個進程效力都不高,2是空間問題,標記清算以后會產生大量不連續的內存碎片,空間碎片太多可能會致使后續使用中沒法找到足夠的連續內存而提早觸發另外一次的垃圾搜集動作。

2.復制算法(Copying

將內存分為1塊較大的eden空間和2塊較少的survivor空間,每次使用eden和其中1塊survivor,當回收時將edensurvivor還存活的對象1次過拷貝到另外1塊survivor空間上,然后清算掉eden和用過的survivor。復制搜集算法在對象存活率高的時候,效力有所降落。

3.標記-整理(Mark-Compact)算法

標記進程依然1樣,但后續步驟不是進行直接清算,而是令所有存活的對象1端移動,然后直接清算掉這端邊界之外的內存。

4.分代搜集(Generational Collection)算法

此算法只是根據對象不同的存活周期將內存劃分為幾塊。1般是把Java堆分作新生代和老年代,這樣就能夠根據各個年代的特點采取最適當的搜集算法。

垃圾搜集器

沒有最好的搜集器,也沒有萬能的搜集器,只有最適合的搜集器。

1.Serial搜集器  
單線程搜集器,搜集時會暫停所有工作線程(我們將這件事情稱之為Stop The World,下稱STW),使用復制搜集算法,虛擬機運行在Client模式時的默許新生代搜集器。  

2.ParNew搜集器  
ParNew搜集器就是Serial的多線程版本,除使用多條搜集線程外,其余行動包括算法、STW、對象分配規則、回收策略等都與Serial搜集器1摸1樣。對應的這類搜集器是虛擬機運行在Server模式的默許新生代搜集器,在單CPU的環境中,ParNew搜集器其實不會比Serial搜集器有更好的效果。  

3.Parallel Scavenge搜集器  
Parallel Scavenge搜集器(下稱PS搜集器)也是1個多線程搜集器,也是使用復制算法,但它的對象分配規則與回收策略都與ParNew搜集器有所不同,它是以吞吐量最大化(即GC時間占總運行時間最小)為目標的搜集器實現,它允許較長時間的STW換取總吞吐量最大化。  

4.Serial Old搜集器  
Serial Old是單線程搜集器,使用標記-整理算法,是老年代的搜集器,上面3種都是使用在新生代搜集器。  

5.Parallel Old搜集器  
老年代版本吞吐量優先搜集器,使用多線程和標記-整理算法,JVM 1.6提供,在此之前,新生代使用了PS搜集器的話,老年代除Serial Old外別無選擇,由于PS沒法與CMS搜集器配合工作。  

6.CMSConcurrent Mark Sweep)搜集器  
CMS是1種以最短停頓時間為目標的搜集器,使用CMS其實不能到達GC效力最高(整體GC時間最小),但它能盡量下降GC時服務的停頓時間,這1點對實時或高交互性利用(比方證券交易)來講相當重要,這類利用對長時間STW1般是不可容忍的。CMS搜集器使用的是標記-清除算法,也就是說它在運行期間會產生空間碎片,所以虛擬機提供了參數開啟CMS搜集結束后再進行1次內存緊縮。

內存分配與回收策略 

       分析實驗數據與結果。

總結

       GC在很多時候都是系統并發度的決定性因素,虛擬機之所以提供多種不同的搜集器,提供大量的調理參數,是由于只有根據實際利用需求、實現方式選擇最優的搜集方式才能獲得最好的性能。沒有固定搜集器、參數組合,也沒有最優的調優方法,虛擬機也沒有甚么必定的行動。


3虛擬機性能監控與故障處理工具

概述

       給1個系統問題定位問題的時候,知識、經驗是關鍵基礎,數據是根據,工具是應用知識處理數據的手段。這里說的數據包括:運行日志、異常堆棧、GC日志、線程快照(threaddump/javacore)、堆轉儲快照(headdump/hprof)等。常常使用適當的虛擬機監控和分析的工具可以加快我們分析數據和定位解決問題的速度。

JDK的命令行工具

       jdk的命令行工具都放置在jdk/bin目錄下,其中包括了我們很熟習的javajavac等工具。這些工具大多都是jdk/lib/tools.jar類庫的1層包裝而已,它們真實的主要功能都是在tools類庫中實現的。下面將介紹幾個經常使用的虛擬機監控工具。

1.jps: JVM Process Status Tool ,顯示指定系統內所有的HotSpot虛擬機進程

可以列出正在運行的虛擬機進程,并顯示虛擬機履行主類的名稱,和這些進程的本地虛擬機的唯1ID(LVMIDLocal Virtual Machine Identifier)。雖然功能單1,但是它是使用最頻繁的工具。LVMID與系統中的進程IDPID)是1樣的。如果同時啟動了多個虛擬機進程,沒法根據進程名稱定位時,那就只能依賴jps命令顯示主類的功能才能辨別。

    命令格式:jps [option] [hostid]

履行樣例:C:\Documents andSettings\Administrator>jps –lmv

2. jstat: JVM Statistics Monitoring Tool, 用于搜集HotSpot虛擬機各方面的運行數據

用于監視虛擬機各種運行狀態信息的命令行工具。它可以顯示本地或遠程虛擬機進程中的類裝載、內存、垃圾搜集、JIT編譯等運行數據,它是將運行期定位虛擬機性能問題的首選工具。

命令格式:jstat [option vmid [interval [s|ms] [count]]]

履行樣例:C:\Documents andSettings\Administrator>jstat -gc 6820 1000 3代表在進程6820,查詢間隔1000毫秒,次數3,查詢參數為-gc

3. jinfo: Configuration Info for Java , 顯示虛擬機配置信息

jinfo的作用是實時地查看和調劑虛擬機的各項參數。使用jps命令的-v參數可以查看虛擬機啟動時顯示指定的參數列表,在JDK1.6以后,jinfo還加入了運行期修改參數的能力,可使用-flag [+|-] name  -flag name=value

     命令格式:jinfo [option] pid

4. jmap: Memeory Map for Java, 生成虛擬機的內存轉儲快照(headdump文件)

jmap1般用于生成堆轉儲快照。固然jmap的作用也不單單是為了獲得dump文件,它還可以查詢finalize履行隊列,Java堆和永久代得詳細信息,如空間使用率、當前使用搜集器等。

      命令格式:jmap [option] vmid

5.jstack: Stack Trace for Java,顯示虛擬機的線程快照

       此命令用于生成虛擬機當前時刻的線程快照。它就是當前虛擬機內每條線程正在履行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的緣由:線程間死鎖、死循環、要求外部資源致使的長時間等待等。

       命令格式:jstack [option] vmid

6.JConsoleJava監視與管理控制臺

JConsole是1個基于JMX的GUI工具,用于連接正在運行的JVM,不過此JVM需要使用可管理的模式啟動。如果要把1個利用以可管理的情勢啟動,可以在啟動是設置com.sun.management.jmxremote。除此以外,還可以用JConsole監控tomacat。

JConsole可以以3種方式連接正在運行的JVM:

  • Local:使用JConsole連接1個正在本地系統運行的JVM,并且履行程序的和運行JConsole的需要是同1個用戶。JConsole使用文件系統的授權通過RMI連接器連接到平臺的MBean服務器上。這類從本地連接的監控能力只有Sun的JDK具有
  • Remote:使用下面的URL通過RMI連接器連接到1個JMX代理:
    service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi。hostName填入主機名稱,portNum為JMX代理啟動時指定的端口。JConsole為建立連接,需要在環境變量中設置mx.remote.credentials來指定用戶名和密碼從而進行授權。
  • Advanced:使用1個特殊的URL連接JMX代理。1般情況使用自己定制的連接器而不是RMI提供的連接器來連接JMX代理,或是1個使用JDK1.4的實現了JMX和JMX Rmote的利用。

當JConsole成功建立連接,它從連接上的JMX代理處獲得信息,并且以下面幾個標簽頁顯現信息。

  • Summary tab. 監控JVM和1些監控變量的信息。
  • Memory tab. 內存使用信息
  • Threads tab. 線程使用信息
  • Classes tab. 類調用信息
  • VM tab. JVM的信息
MBeans tab.所有MBeans的信息
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 欧美黄区 | 91精品欧美一区二区综合在线 | 久久久久久综合成人精品 | 91精品国产人成网站 | 成人看片又黄又爽 | 欧美国产日韩1区俺去了 | 九一国产精品 | freehdvideo性欧美 | 性高湖久久久久久久久aaaaa | 网站视频大片www | 美国人和狍xxxx视频 | 亚洲经典在线中文字幕 | 亚洲视频在线一区二区 | 亚洲一区精品中文字幕 | 亚洲伊人成综合网 | 欧美在线精品永久免费播放 | 激情久久久久久久久久久 | 色就色欧美综合偷拍区a | 亚洲高清一区二区三区四区 | 亚洲在线中文字幕 | 国产精品三区四区 | 青青草原在线视频免费观看 | 色综合欧美亚洲另类久久 | 福利视频一二区 | 国产亚洲精品久久久久91网站 | 久久精品二三区 | jizz亚洲日本jizz | 国产拍拍拍免费专区在线观看 | 国产精品福利在线观看入口 | 一区二区三区在线免费视频 | 亚洲国产成人精品一区二区三区 | 精品成人网 | 免费高清毛片在线播放视频 | 免费观看又污又黄网站日本 | 中文亚洲动漫精品 | 国产亚洲自拍一区 | 成年人的天堂 | 国产第一区二区三区在线观看 | 亚洲视频一区二区三区 | 亚洲精品二区 | 老司机午夜免费 |