欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java垃圾回收器的方法和原理總結(jié)

 更新時間:2016年12月15日 09:08:59   作者:kimy  
本篇文章主要介紹了Java垃圾回收器的方法和原理總結(jié),Java垃圾回收器是Java虛擬機的重要模塊,具有一定的參考價值,有興趣的可以了解一下。

什么是Java垃圾回收器

Java垃圾回收器是Java虛擬機(JVM)的三個重要模塊(另外兩個是解釋器和多線程機制)之一,為應(yīng)用程序提供內(nèi)存的自動分配(Memory Allocation)、自動回收(Garbage Collect)功能,這兩個操作都發(fā)生在Java堆上(一段內(nèi)存快)。某一個時點,一個對象如果有一個以上的引用(Rreference)指向它,那么該對象就為活著的(Live),否則死亡(Dead),視為垃圾,可被垃圾回收器回收再利用。垃圾回收操作需要消耗CPU、線程、時間等資源,所以容易理解的是垃圾回收操作不是實時的發(fā)生(對象死亡馬上釋放),當內(nèi)存消耗完或者是達到某一個指標(Threshold,使用內(nèi)存占總內(nèi)存的比列,比如0.75)時,觸發(fā)垃圾回收操作。有一個對象死亡的例外,java.lang.Thread類型的對象即使沒有引用,只要線程還在運行,就不會被回收。

回收的機制

依據(jù)統(tǒng)計分析可知,Java(包括一些其它高級語言)里面大多數(shù)對象生命周期都是短暫的,所以把Java內(nèi)存分代管理。分代的目的無非就是為不同代的內(nèi)存塊運用不同的管理策略(算法),從而最大化性能。相對于年老代,通常年輕代要小很多,回收的頻率高,速度快。年老代則回收頻率低,耗時長。內(nèi)存在年輕代里面分配,年輕代里面的對象經(jīng)過多個回收周期依然存活的會自動晉升到年老代。

設(shè)計選型(Design Choices)

設(shè)計選型影響JVM垃圾回收器的實現(xiàn)難度,以及JVM的性能指標,適用于不同的場景。描述的是回收算法的風格特點。

單線程串行回收 VS 多線程并行回收

回收操作自身是否多線程處理的問題。單線程回收的優(yōu)點是簡單,易實現(xiàn),碎片少,適用于單核的機器。多線程并行回收在多核機器上面可以充分的利用CPU資源,減少回收的時間,增加生產(chǎn)力,缺點是復(fù)雜且可能有部分碎片沒有回收。

回收時暫停應(yīng)用線程 VS 回收和應(yīng)用并發(fā)進行

回收操作時是否暫停應(yīng)用線程的問題。暫停應(yīng)用線程的優(yōu)點是簡單、準確、清理得比較干凈、清理的時間也短(CPU資源獨占),缺點是暫停應(yīng)用線程之后會造成垃圾回收周期內(nèi)應(yīng)用的回應(yīng)時間拉長,實時性非常高的系統(tǒng)比較敏感。回收和應(yīng)用線程并行處理的優(yōu)點是應(yīng)用反應(yīng)時間比較平穩(wěn)、缺點是實現(xiàn)難度大、清理頻率高、可能有碎片。

不合并釋放的內(nèi)存片段 VS 合并釋放的內(nèi)存片段 VS 把活著的復(fù)制到新的地方

這三個選型描述的是如何管理死亡的內(nèi)存塊片段。死亡的內(nèi)存片段通常散落在堆的各個地方,如果不加以管理會有兩個問題,內(nèi)存分配的時候因查找可用的內(nèi)存而導(dǎo)致速度慢,小的碎片會導(dǎo)致內(nèi)存的浪費(比如大的數(shù)組要求大的連續(xù)內(nèi)存片段)。管理有兩種方式,把活著的內(nèi)存挪到內(nèi)存塊的某一端,記錄可用內(nèi)存的開始位置,或者干脆把活著的內(nèi)存復(fù)制到一個新的內(nèi)存區(qū)域,原來的內(nèi)存塊整個空出來。

性能指標(Performance Metrics)

①、生產(chǎn)率(Throughput)

一個較長的周期(長的周期才有意義)內(nèi),非回收時間占總時間的比率。度量系統(tǒng)的運行效率。

②、垃圾回收花費(Garbage Collection overhead)

一個較長的周期內(nèi),回收時間占總時間的比率。與生產(chǎn)率相對應(yīng),加起來為100%。

③、暫停時間間隔(Pause time)

Java虛擬機在回收垃圾的時候,有的算法會暫停所有應(yīng)用線程的執(zhí)行,某些系統(tǒng)可能對暫停的時間間隔比較敏感。

④、回收的頻率(Frequency of collection)

平均多久會發(fā)生回收操作。

⑤、內(nèi)存占用的大小(Footprint)

如堆的大小。

⑥、實時性(Promptness)

自一個對象死亡起,經(jīng)過多久該對象所占用內(nèi)存被回收。

垃圾回收的類型

所有的回收器類型都是基于分代技術(shù)。Java HotSpot虛擬機包含三代,年輕代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation)。

①永久代

存儲類、方法以及它們的描述信息??梢酝ㄟ^-XX:PermSize=64m和-XX:MaxPermSize=128m兩個可選項指定初始大小和最大值。通常 我們不需要調(diào)節(jié)該參數(shù),默認的永久代大小足夠了,不過如果加載的類非常多,不夠用了,調(diào)節(jié)最大值即可。

②年老代

主要存儲年輕代中經(jīng)過多個回收周期仍然存活從而升級的對象,當然對于一些大的內(nèi)存分配,可能也直接分配到永久代(一個極端的例子是年輕代根本就存不下)。

③年輕代

絕大多數(shù)的內(nèi)存分配回收動作都發(fā)生在年輕代。如下圖所示, 年輕代被劃分為三個區(qū)域,原始區(qū)(Eden)和兩個小的存活區(qū)(Survivor),兩個存活區(qū)按功能分為From和To。絕大多數(shù)的對象都在原始區(qū)分配,超過一個垃圾回收操作仍然存活的對象放到存活區(qū)。

串行回收器(Serial Collector)

單線程執(zhí)行回收操作,回收期間暫停所有應(yīng)用線程的執(zhí)行,client模式下的默認回收器,通過-XX:+UseSerialGC命令行可選項強制指定。

①年輕代的回收算法(Minor Collection)

把Eden區(qū)的存活對象移到To區(qū),To區(qū)裝不下直接移到年老代,把From區(qū)的移到To區(qū),To區(qū)裝不下直接移到年老代,F(xiàn)rom區(qū)里面年齡很大的升級到年老代。 回收結(jié)束之后,Eden和From區(qū)都為空,此時把From和To的功能互換,F(xiàn)rom變To,To變From,每一輪回收之前To都是空的。設(shè)計的選型為復(fù)制。

②年老代的回收算法(Full Collection)

年老代的回收分為三個步驟,標記(Mark)、清除(Sweep)、合并(Compact)。標記階段把所有存活的對象標記出來,清除階段釋放所有死亡的對象,合并階段 把所有活著的對象合并到年老代的前部分,把空閑的片段都留到后面。設(shè)計的選型為合并,減少內(nèi)存的碎片。

并行回收器(Parallel Collector)

使用多個線程同時進行垃圾回收,多核環(huán)境里面可以充分的利用CPU資源,減少回收時間,增加JVM生產(chǎn)率,Server模式下的默認回收器。與串行回收器相同,回收期間暫停所有應(yīng)用線程的執(zhí)行。通過-XX:+UseParallelGC命令行可選項強制指定。

①年輕代的回收算法(Minor Collection)

使用多個線程回收垃圾,每一個線程的算法與串行回收器相同。

②年老代的回收算法(Full Collection)

年老代依然是單線程的,與串行回收器相同。

并行合并收集器(Parallel Compacting Collection)

年輕代和年老代的回收都是用多線程處理。通過命令可選項-XX:+UseParallelOldGC指定,–XX:ParallelGCThreads=3還可進一步指定參與并行回收的線程數(shù)。與串行回收器相同,回收期間暫停所有應(yīng)用線程的執(zhí)行。與并行回收器相比,年老代的回收時間更短,從而減少了暫停時間間隔(Pause time)。通過–XX:+UseParallelOldGC命令行可選項強制指定。

①年輕代的回收算法(Minor Collection)

與并行回收器(Parallel Collector)相同

②年老代的回收算法(Full Collection)

年老代分為三個步驟,標記、統(tǒng)計、合并。這里用到分的思想,把年老代劃分為很多個固定大小的區(qū)(region)。 標記階段,把所有存活的對象劃分為N組(應(yīng)該與回收線程數(shù)相同),每一個線程獨立的負責自己那一組,標記存活對象的位置以及 所在區(qū)(Region)的存活率信息,標記為并行的。統(tǒng)計階段,統(tǒng)計每一個區(qū)(Region)的存活率,原則上靠前面的存活率較高,從前到后, 找到值得合并的開始位置(絕大多數(shù)對象都存活的區(qū)不值得合并),統(tǒng)計階段是串行的(單線程)。合并階段,依據(jù)統(tǒng)計階段的信息,多線程 并行的把存活的對象從一個區(qū)(Region)復(fù)制到另外一個區(qū)(Region)。

并發(fā)標記清除回收器(Concurrent Mark-Sweep Collector)

又名低延時收集器(Low-latency Collector),通過各種手段使得應(yīng)用程序被掛起的時間最短?;九c應(yīng)用程序并發(fā)地執(zhí)行回收操作,沒有合并和復(fù)制操作。通過命令行-XX:+UseConcMarkSweepGC指定,在單核或者雙核系統(tǒng)里面還可以指定使用增量式回收模式-XX:+UseConcMarkSweepGC。增量式回收是指把回收操作分為多個片段,執(zhí)行一個片段之后釋放CPU資源給應(yīng)用程序,未來的某個時點接著上次的結(jié)果繼續(xù)回收下去。目的也是減少延時。

①年輕代的回收算法(Minor Collection)

與并行回收器(Parallel Collector)相同

②年老代的回收算法(Full Collection)

分為四個步驟,初始標記(Initial Mark)、并發(fā)標記(Concurrent Mark)、再次標記(Remark)、以及并發(fā)清理(Concurrent Sweep)。特別注意,沒有合并操作,所以會有碎片。

  • 初始化階段: 暫停應(yīng)用線程,找出所有存活的對象,耗時比較短,回收器使用單線程。
  • 并發(fā)標記階段: 回收器標記操作與應(yīng)用并發(fā)運行,回收器使用單線程標記存活對象。
  • 再次標記:并發(fā)標記階段由于應(yīng)用程序也在運行,這個過程中可能新增或者修改對象。所以再次暫停應(yīng)用線程,找出所有修改的對象,使用多線程標記。
  • 并發(fā)清理:回收器清理操作與應(yīng)用并發(fā)運行,回收器使用單線程清理死亡對象。

Java垃圾回收器的性能評估工具

①–XX:+PrintGCDetails和–XX:+PrintGCTimeStamps

垃圾回收的開始時間,持續(xù)時間,每一代的空余內(nèi)存等信息。

②jmap [options] pid

jamp 2043 查看2043進程里面已經(jīng)加載的共享對象。通常DLL文件。

jmap -heap 2043 查看內(nèi)存堆的配置信息以及使用情況。

jmap -permstat 2043 查看永久代的加載情況。

jmap -histo 2043 查看類的加載和內(nèi)存占用情況。

③jstat [options] pid

jstat -class 2043 class加載、卸載、內(nèi)存占用情況。

jstat -gc 2043 GC執(zhí)行情況。

后記

Java提供自動選擇和自動性能優(yōu)化功能。在做垃圾回收器調(diào)優(yōu)之前,先列出所關(guān)注的性能指標,通過命令行告訴JVM你所關(guān)注的性能指標,由JVM自動調(diào)優(yōu),如果不滿意,可以指定垃圾回收器。OutOfMemory通常是由于堆內(nèi)存不足,調(diào)節(jié)-Xmx1024m和-XX:MaxPermSize=128m命令行可選項即可。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java面試題篇之Sleep()方法與Wait()方法的區(qū)別詳解

    Java面試題篇之Sleep()方法與Wait()方法的區(qū)別詳解

    這篇文章主要給大家介紹了關(guān)于Java面試題篇之Sleep()方法與Wait()方法區(qū)別的相關(guān)資料,wait()是Object類中的方法,而sleep()是Thread類中的靜態(tài)方法,wait()方法用于多個線程之間的協(xié)作和通信,而sleep()方法用于線程的休眠,需要的朋友可以參考下
    2024-07-07
  • SpringBoot靜態(tài)資源路徑配置及主頁顯示

    SpringBoot靜態(tài)資源路徑配置及主頁顯示

    這篇文章主要介紹了SpringBoot靜態(tài)資源路徑配置及主頁顯示,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • java實現(xiàn)汽車租賃系統(tǒng)

    java實現(xiàn)汽車租賃系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)汽車租賃系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Spring Batch讀取txt文件并寫入數(shù)據(jù)庫的方法教程

    Spring Batch讀取txt文件并寫入數(shù)據(jù)庫的方法教程

    這篇文章主要給大家介紹了Spring Batch讀取txt文件并寫入數(shù)據(jù)庫的方法,SpringBatch 是一個輕量級、全面的批處理框架。這里我們用它來實現(xiàn)文件的讀取并將讀取的結(jié)果作處理,處理之后再寫入數(shù)據(jù)庫中的功能。需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • java中l(wèi)ist使用時需避免的場景總結(jié)

    java中l(wèi)ist使用時需避免的場景總結(jié)

    眾所周知,Java為開發(fā)者提供了多種集合類的實現(xiàn),其中幾乎所有業(yè)務(wù)代碼都需要用到List,但List的錯誤使用也會導(dǎo)致諸多問題,所以本文我們就來看一看幾個錯誤使用List的場景吧
    2023-10-10
  • Mybatis邏輯分頁與物理分頁PageHelper使用解析

    Mybatis邏輯分頁與物理分頁PageHelper使用解析

    這篇文章主要為大家介紹了Mybatis邏輯分頁與物理分頁PageHelper使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 使用@Autowired 注入RedisTemplate報錯的問題及解決

    使用@Autowired 注入RedisTemplate報錯的問題及解決

    這篇文章主要介紹了使用@Autowired 注入RedisTemplate報錯的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java設(shè)計模式之訪問者模式使用場景及代碼示例

    Java設(shè)計模式之訪問者模式使用場景及代碼示例

    這篇文章主要介紹了Java設(shè)計模式之訪問者模式使用場景及代碼示例,小編覺得還是挺不錯的,這里分享給大家,供需要的朋友參考。
    2017-11-11
  • 詳解Spring注解 @Configuration

    詳解Spring注解 @Configuration

    @Configuration 是 Spring 中的一個注解,它用于標記一個類為配置類,通過配置類可以定義和組裝 Spring Bean,并且支持高度靈活的配置方式。本問詳細介紹了Spring注解 @Configuration,感興趣的小伙伴可以參考一下
    2023-04-04
  • java synchronized關(guān)鍵字的用法

    java synchronized關(guān)鍵字的用法

    synchronized關(guān)鍵字我們大家都知道是線程同步關(guān)鍵字.總結(jié)一下日常的使用方法,還有一個坑.
    2016-05-05

最新評論