Java虛擬機基本結構的簡單記憶

Java堆:通常是放置實例化的對象的地方,堆分新生代和老年代空間,不斷未被回收的對象越老,被放入老年代空間。分配最大堆空間:-Xmx     分配初始堆空間:-Xms,分配新生代空間:-Xmn,新生代的大小通常爲整個堆空間的1/3到1/4。新生代通常分爲eden和survivor(from,to)區。新生代被GC15(配置參數-XX:MaxTenuringThreshold,默認15)次後仍存活,進入老年代,但也可能提早晉升,由survivor區決定。新生代和老年代都屬於JVM的Heap區,另外還有一個持久代Perm區,又叫永久區,是一塊線程共享的內存區域,大小決定了系統能夠保存多少個類,定義太多的類,會拋出內存溢出錯誤。分配永久區空間:-XX:PermSize和-XX:MaxPermSize(默認爲64M)。算法

Java棧:放置對象的方法函數的地方,全部的方法的內部變量在Java棧中,之後進先出的方式不斷進棧出棧,出棧即被銷燬。對於徹底不會被其餘線程訪問的對象,能夠分配在棧上,而不是分配在堆上,當方法結束後便自行銷燬。分配棧空間:-Xss緩存

JVM垃圾回收的幾種方法:多線程

一、標記清除法,標記全部從根節點開始的可達對象,未被標記的對象就是未被引用的垃圾對象,標記清除算法可能產生的最大問題就是空間碎片。標記操做完成後,系統回收全部不可達的空間。併發

二、複製算法。將原有的內存空間分爲兩塊,每次只使用其中一塊,經過標記清除法後,將存活對象複製到另外一塊內存空間,並保持連續,沒有空間碎片。而後清空原內存空間。主要用在新生代的垃圾回收中,由於在新生代,垃圾對象一般會多於存活對象。函數

三、標記壓縮法。在標記清除法的基礎上,再進行一次碎片整理。使得沒有空間碎片,一般用於老年代。性能

四、分代算法。根據新生代和老年代的不一樣,分別使用以上算法。另外爲了高效回收新生代,在老年代的掃描中一般使用卡表。卡表用來表示老年代的某一區域中的全部對象是否持有新生代對象的引用,在新生代GC時能夠不用花大量時間掃描全部老年代對象,只有卡表的標記爲1時,才掃描給定區域的老年代對象,卡表爲0則不掃描。線程

五、分區算法。將整個堆空間劃分紅連續的不一樣小空間,每一個小空間都獨立使用,獨立回收。在相同條件下,堆空間越大,一次GC所須要的時間越長,從而產生的停頓也越長,爲了更好的控制GC的停頓時間,每次合理地回收若干小區間,而不是整個堆空間,從而減小一次GC所產生的停頓。日誌

垃圾收集器的種類(如下凡是隻指定新生代的,老年代都是使用串行回收器)對象

一、串行回收器。單線程,獨佔式。串行回收時,全部線程都須要暫停。使用-XX:+UseSerialGC,表示新生代和老年代都使用串行回收器,新生代是複製,老年代是標記壓縮。新生代日誌標記DefNew,老年代日誌標記Full GC.內存

2.一、並行回收器。ParNew回收器,新生代的垃圾收集器。簡單將串行回收器多線程化,獨佔式。在併發能力比較強的CPU上,產生的停頓時間短於串行回收器。使用-XX:+UseParNewGC。線程數量使用-XX:ParallelGCThreads指定。最好與CPU數量至關,CPU數量小於8時,值爲CPU數量,大於8時,值爲3+((5*CPU_Count)/8)。日誌標記ParNew。-XX:PretenureSizeThreshold設置對象直接晉升老年代的閾值,只對以上兩種回收器有效。

2.二、並行回收器。新生代ParallelGC回收器,很是關注系統吞吐量。使用-XX:+UseParallelGC。控制系統吞吐量的兩個重要參數,-XX:MaxGCPauseMillis:設置最大垃圾收集停頓時間,值大於0的整數,工做時會調整Java堆大小,若是值設的很小,JVM會使用較小的堆,致使垃圾收集變的很頻繁。-XX:GCTimeRatio:設置吞吐量大小。值0到100之間的整數。值爲n時,系統花費不超過1/(1+n)的時間用於垃圾收集。-XX:+UseAdaptiveSizePolicy能夠打開自適應GC策略,自動調整eden,survivior的比例,晉升老年代的對象年齡等。以達到在堆大小,吞吐量和停頓時間之間的平衡點。手工調困難場合下使用,指定最大堆-Xmx,目標吞吐量-XX:GCTimeRatio,停頓時間-XX:MaxGCPauseMillis,讓JVM自動調優。日誌標記,PSYoungGen.注:吞吐量和吞吐時間是互相矛盾的,減小停頓時間會減小系統吞吐量,增長吞吐量會增長最大停頓。

2.三、並行回收器。老年代ParallelOldGC回收器。使用-XX:+UseParallelOldGC,新生代則會使用ParallelGC回收器。-XX:ParallelGCThreads設置線程數量。日誌標誌Full GC[PSYoungGen].

三、CMS回收器:標記型多線程回收器,通常工做在老年代,新生代使用ParNew回收器。分初始標記,併發標記,預清理,從新標記,併發清理,併發重置幾個階段,其中初始標記跟從新標記是系統獨佔的。預清理是併發的(垃圾回收線程跟應用線程同時進行),能夠關閉開關-XX:-CMSPrecleaningEnabled,不進行預清理。啓用CMS回收器的參數:-XX:+UseConcMarkSweepGC。默認併發線程數(ParallelGCThreads+3)/4,ParallelGCThreads表示GC並行(應用程序中止,同時多個線程一塊兒執行GC)時使用的線程數量。併發線程數量也能夠經過-XX:ConcGCThreads或者-XX:ParallelCMSThreads參數設置。由於CMS整體不是獨佔的,在回收過程當中,應用程序依然會產生垃圾,因此當堆內存達到必定閾值是開始回收,該閾值可使用-XX:CMSInitiatingOccupancyFraction來設置,默認是68。調優方法,當內存增加緩慢,增大閾值,下降CMS觸發頻率,當內存增加很快,下降閾值,避免頻繁觸發老年代串行收集器(老年代收集時,應用程序將徹底中止,停頓時間較長)。-XX:+UseCMSCompactAtFullCollection開關可使CMS在垃圾收集完成後進行一次碎片整理。-XX:CMSFullGCsBeforeCompaction參數能夠設置多少次CMS回收後,進行一次碎片整理。日誌標記:初始標記[CMS-initial-mark],開始併發標記 [CMS-concurrent-mark-start],開始併發結束標記 [CMS-concurrent-mark],預清理標記 [CMS-concurrent-preclean-start] ,預清理標記費時 [CMS-concurrent-preclean: 0.017/0.018 secs] ,預清理開始[CMS-concurrent-abortable-preclean-start],預清理結束費時[CMS-concurrent-abortable-preclean: 0.011/0.014 secs],從新標記[CMS-remark],開始併發清理 [CMS-concurrent-sweep-start] ,併發重置 [CMS-concurrent-reset-start] 。CMS回收器是一個關注停頓的垃圾收集器。若是要回收Perm(永久區),須要打開-XX:+CMSClassUnloadingEnabled開關。

四、G1回收器,分代分區回收器,實現了分代分區算法。可使用-XX:+UseG1GC標記打開G1收集器開關。回收過程有4個階段。一、新生代GC.二、併發標記週期.三、混合收集.四、若是須要,可能會進行Full GC。新生代GC的主要工做時回收eden區和survivor區,一旦eden區被佔滿,就會啓動,清空eden區,並複製到survivor區,因此GC一次,eden區變0,survivor增大。日誌標記[GC pause (young)]。併發標記階段跟CMS相似,分初始標記,根區域掃描,併發標記,從新標記,獨佔清理,併發清理。併發標記週期並不清理大量垃圾,只是標記了一些含有大量垃圾的G區域,交給混合收集去清理。混合收集階段會清理標記爲G的區域,並把存活的對象移動到其餘區域。日誌標記[GC pause (mixed)]。必要時的Full GC,由於應用程序跟GC線程交替工做,不免出現內存不足,這種狀況時會產生一次Full GC.目標最大停頓時間參數-XX:MaxGCPauseMillis,若是設的太短,新生代GC次數會增長,老年代在混合收集時,會減小收集的區域數量,從而增長了Full GC的可能性。並行回收時,工做線程數量參數-XX:ParallelGCThreads。-XX:InitiatingHeapOccupancyPercent參數指定堆使用率多少時,觸發併發標記週期的執行,默認爲45,即整個堆佔用率達到45%時,執行併發標記週期。設置過大會致使併發週期遲遲不啓動,引發Full GC的可能性增大。太小會使得併發週期很是頻繁,大量GC線程搶佔CPU,致使應用程序的性能降低。

五、TLAB,線程本地分配緩存,線程專屬分配對象區間,避免多線程衝突。自己佔用eden區的空間。開啓爲-XX:+UseTLAB(關閉爲-UseTLAB)。使用-XX:TLABSize指定一個TLAB的大小,-XX:-ResizeTLAB禁用從新分配大小。當分配的對象大於TLAB剩餘空間時,由-XX:TLABRefillWasteFraction來設置一個閾值,假如爲n(默認值爲64),表示爲1/n的空間大小,當對象大小大於1/n時,分配在堆上,若是小於,則廢棄該TLAB,新建TLAB來分配該對象。日誌,desired_size爲TLAB大小,slow allocs上一次新生代GC到如今爲止慢分配(對象直接分配到堆上)次數,refill waste分配閾值,alloc當前線程的TLAB分配比例和使用評估量,refills表示該線程的TLAB空間被從新分配並填充的次數,waste表示空間的浪費比例。TLAB totals中,thrds相關線程總數,refills全部線程refills的總數,其後的max表示refills次數最多的線程的refills次數。

最後說一下new一個對象的過程,先棧上分配(通常在方法中)(不成功)->TLAB分配(不成功)->eden分配(或者老年代分配,根據對象大小)。

相關文章
相關標籤/搜索