日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > 架構(gòu)師社區(qū)
[導(dǎo)讀]jvm運(yùn)行時(shí)數(shù)據(jù)區(qū)Java程序啟動(dòng)后,本質(zhì)上就是啟動(dòng)一個(gè)jvm進(jìn)程,jvm會(huì)將自己管理的內(nèi)存劃分為幾個(gè)區(qū)域,每個(gè)區(qū)域都有自己的用途。在程序運(yùn)行時(shí)的內(nèi)存區(qū)域主要可以劃分為五個(gè),分別是:方法區(qū)、堆、虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器??梢杂孟旅娴膱D來描述:圖1?jvm運(yùn)行時(shí)數(shù)據(jù)區(qū)jvm...

jvm運(yùn)行時(shí)數(shù)據(jù)區(qū)


Java程序啟動(dòng)后,本質(zhì)上就是啟動(dòng)一個(gè)jvm進(jìn)程,jvm會(huì)將自己管理的內(nèi)存劃分為幾個(gè)區(qū)域,每個(gè)區(qū)域都有自己的用途。在程序運(yùn)行時(shí)的內(nèi)存區(qū)域主要可以劃分為五個(gè),分別是:方法區(qū)、堆、虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器。可以用下面的圖來描述:

一文詳解,jvm內(nèi)存分代與垃圾回收原理

圖1?jvm運(yùn)行時(shí)數(shù)據(jù)區(qū)


jvm堆內(nèi)存分代


我們創(chuàng)建的對(duì)象,都會(huì)進(jìn)入Java堆內(nèi)存中,堆內(nèi)存的分代模型分為:年輕代、老年代、永久代。


其實(shí)大部分對(duì)象的存活周期都是極短的,比如我們?cè)诜椒ɡ飫?chuàng)建一個(gè)對(duì)象,離開這個(gè)方法后,這個(gè)對(duì)象的生命周期就結(jié)束了。一旦這個(gè)對(duì)象沒人使用了,就需要被jvm回收掉,釋放內(nèi)存空間。


少數(shù)對(duì)象是長期存活的,比如spring容器中創(chuàng)建的bean,一般都會(huì)一直存活在容器中。


每個(gè)對(duì)象的存活時(shí)間差別巨大,那么就需要差別化管理,就像城市規(guī)劃中,會(huì)劃分出生活區(qū),商業(yè)區(qū),制造業(yè)區(qū)。


于是jvm就有了分代模型,年輕代、老年代,jvm將堆內(nèi)存分為了這兩個(gè)區(qū)域。


年輕代,顧名思義,就是對(duì)象創(chuàng)建和使用完之后,很快就要回收的對(duì)象放在里面。


老年代呢,就是對(duì)象創(chuàng)建之后需要長期存在的對(duì)象放在里面,如下圖:

一文詳解,jvm內(nèi)存分代與垃圾回收原理

圖2 jvm堆內(nèi)存分代


堆內(nèi)存分為年輕代、老年代,這跟垃圾回收有關(guān),對(duì)于年輕代里的對(duì)象,它們的特點(diǎn)是創(chuàng)建之后很快就會(huì)被回收,所以需要用一種垃圾回收算法。


對(duì)于老年代里的對(duì)象,他們的特點(diǎn)是需要長期存在,所以需要另外一種垃圾回收算法,所以需要分成兩個(gè)區(qū)域來放不同的對(duì)象。


對(duì)象的分配與流轉(zhuǎn)


一般來說,對(duì)象都是優(yōu)先分配在年輕代的。

public?class Server {????private?static ConfigLoader loader = new ConfigLoader();????public static void main(String[] args) {????????loadLocalConfig();????????while (true) {???????? loadConfigFromRemote();????????????Thread.sleep(1000);????????}????}????????private?static?void?loadLocalConfig() {????????ConfigManager?configManager = new ConfigManager();????????configManager.load();????}????private static void loadConfigFromRemote() {????????loader.load();????}}類靜態(tài)變量loader引用的那個(gè)ConfigLoader對(duì)象,首先分配在年輕代,是長期存活在內(nèi)存里的。loadLocalConfig方法中創(chuàng)建的configManager對(duì)象也是分配在新時(shí)代里的。

一文詳解,jvm內(nèi)存分代與垃圾回收原理

?圖3 對(duì)象優(yōu)先分配在新生代

什么時(shí)候觸發(fā)新生代的垃圾回收?


當(dāng)方法loadLocalConfig執(zhí)行完后,這個(gè)方法堆棧出棧,就沒有任何局部變量引用configManager對(duì)象了。


那么jvm就會(huì)立馬回收掉分配給它的內(nèi)存嗎?


不會(huì)的!如果新生代的內(nèi)存空間,幾乎都被全部對(duì)象給占滿了!此時(shí)假設(shè)我們代碼繼續(xù)運(yùn)行,需要在新生代里去分配一個(gè)對(duì)象,發(fā)現(xiàn)內(nèi)存不夠了,這個(gè)時(shí)候就會(huì)觸發(fā)一次新生代的內(nèi)存回收。


新生代內(nèi)存空間的垃圾回收,也稱之為Minor GC或Young GC,它會(huì)嘗試把新生代里沒人引用的對(duì)象給回收掉。


對(duì)象是有年齡的,如果對(duì)象在一次垃圾回收后還存活,那么它的年齡就會(huì)加1。


默認(rèn)情況下,如果成功躲過了15次垃圾回收,也就是15歲,還沒被回收掉,然后它會(huì)被轉(zhuǎn)移到Java堆內(nèi)存的老年代中去,顧名思義,老年代就是放這些年齡很大的對(duì)象。


什么情況下一個(gè)對(duì)象會(huì)被回收掉?


簡單來說一個(gè)對(duì)象不再被使用了,就會(huì)被垃圾回收掉,但jvm怎么判斷一個(gè)對(duì)象是否會(huì)繼續(xù)使用呢?


jvm使用了一種可達(dá)性分析的算法來判斷對(duì)象是不是可以被回收掉。


可達(dá)性分析法,是通過從GCRoots出發(fā),找出內(nèi)存中的引用鏈,那么鏈中的對(duì)象表示可達(dá),即不能被垃圾回收。引用鏈之外的對(duì)象即可作為垃圾回收。


jvm中GC Roots有這幾種:


  • 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象
  • 方法區(qū)中類靜態(tài)屬性引用的對(duì)象
  • 方法區(qū)中常量引用的對(duì)象
  • 本地方法棧中JNI(即一般說的native方法)中引用的對(duì)象

其中,局部變量和類靜態(tài)變量比較常見。需要注意的是,類實(shí)例變量不是GC Roots。


年輕代的垃圾回收算法


新生代內(nèi)存區(qū)域劃分為三塊:1個(gè)Eden區(qū),2個(gè)Survivor區(qū),默認(rèn)情況下Eden區(qū)占80%內(nèi)存空間,每一塊Survivor區(qū)各占10%內(nèi)存空間,


比如說新生代1G的內(nèi)存,Eden區(qū)就有800MB內(nèi)存,每一塊Survivor區(qū)就有100MB內(nèi)存,如下圖。

一文詳解,jvm內(nèi)存分代與垃圾回收原理

圖4 新生代內(nèi)存劃分


剛開始對(duì)象都是分配在Eden區(qū)內(nèi)的,如果Eden區(qū)快滿了,此時(shí)就會(huì)觸發(fā)垃圾回收。


新生代使用的復(fù)制算法,此時(shí)就會(huì)把Eden區(qū)中的存活對(duì)象都一次性轉(zhuǎn)移到一塊空著的Survivor區(qū)。survivor的中文意思是存活,顧名思義,就是放垃圾回收后存活的對(duì)象的。


接著Eden區(qū)就會(huì)被清空,然后再次分配新對(duì)象就會(huì)繼續(xù)分配到Eden區(qū)里,這樣只有Eden區(qū)和一塊Survivor區(qū)里是有對(duì)象的,其中Survivor區(qū)里放的是上一次Minor GC后存活的對(duì)象。新生代的垃圾回收就是這樣來回倒騰的。


所以1G內(nèi)存的新生代,平時(shí)可以使用的,就是Eden區(qū)和其中一塊Survivor區(qū),那么相當(dāng)于有900MB的內(nèi)存是可以使用。


這么做最大的好處,就是只有10%的內(nèi)存空間是被閑置的,90%的內(nèi)存都被用上了。新生代對(duì)象存活期很短,存活的對(duì)象也很少,所以survivor分配的區(qū)域也比較小。


對(duì)象何時(shí)進(jìn)入老年代?


對(duì)象一般優(yōu)先分配在年輕代,那么何時(shí)進(jìn)入老年代呢?有這幾種情況:


  • 躲過15次垃圾回收后


具體多少歲進(jìn)入老年代,可以通過JVM參數(shù)-XX:MaxTenuringThreshold來設(shè)置,默認(rèn)是15歲。


  • 動(dòng)態(tài)年齡判斷


他的大致規(guī)則就是,假如說當(dāng)前存放對(duì)象的Survivor區(qū)域里,一批對(duì)象的總大小大于了這塊Survivor區(qū)域的內(nèi)存大小的50%,那么此時(shí)大于等于這批對(duì)象年齡的對(duì)象,就可以直接進(jìn)入老年代了。


規(guī)則看起來比較晦澀,通俗理解就是:年齡1 年齡2 年齡n的多個(gè)年齡對(duì)象總和超過了Survivor區(qū)域的50%,此時(shí)就會(huì)把年齡n以上的對(duì)象都放入老年代。


  • 大對(duì)象直接進(jìn)入老年代


多大對(duì)象算大對(duì)象,可以通過JVM參數(shù)“-XX:PretenureSizeThreshold”來設(shè)置,可以把它的值設(shè)置為字節(jié)數(shù),比如“1048576”字節(jié),就是1MB。


之所以這么做,就是要避免新生代里出現(xiàn)那種大對(duì)象,屢次躲過GC,還得把他在兩個(gè)Survivor區(qū)域里來回復(fù)制多次之后才能進(jìn)入老年代,


  • Minor GC后對(duì)象太多Survivor放不下,把這些對(duì)象直接轉(zhuǎn)移到老年代去


有可能Eden區(qū)垃圾回收后,存活的對(duì)象太多,survivor放不下只能轉(zhuǎn)移到老年代去。


空間分配擔(dān)保機(jī)制


在發(fā)生Minor GC之前,JVM會(huì)先檢查一下老年代最大可用的連續(xù)內(nèi)存空間,是否大于新生代所有對(duì)象的總大小。


因?yàn)闃O端的情況下,可能新生代Minor GC過后,存活對(duì)象太多了,survivor放不下。


如果說發(fā)現(xiàn)老年代的內(nèi)存大小是大于新生代所有對(duì)象的,此時(shí)就可以放心大膽的對(duì)新生代發(fā)起一次Minor GC了,因?yàn)榧词筂inor GC之后所有對(duì)象都存活,Survivor區(qū)放不下了,也可以轉(zhuǎn)移到老年代去。


如果Minor GC之后新生代的對(duì)象全部存活下來,然后全部需要轉(zhuǎn)移到老年代去,但是老年代空間又不夠怎么辦?


那么就要看看老年代的內(nèi)存大小,是否大于之前每一次Minor GC后進(jìn)入老年代的對(duì)象的平均大小。


如果老年代連續(xù)空閑空間大于新生代對(duì)象總大小,或者大于之前每一次Minor GC后進(jìn)入老年代對(duì)象平均大小,就只觸發(fā)Minor GC,否則就要觸發(fā)Full GC。


假如此時(shí)進(jìn)行Minor GC也有幾種可能:


(1)Minor GC過后,剩余的存活對(duì)象的大小,是小于Survivor區(qū)的大小的,那么此時(shí)存活對(duì)象進(jìn)入Survivor區(qū)域即可。


(2)Minor GC過后,剩余的存活對(duì)象的大小,是大于 Survivor區(qū)域的大小,但是是小于老年代可用內(nèi)存大小的,此時(shí)就直接進(jìn)入老年代即可。


(3)Minor GC過后,剩余的存活對(duì)象的大小,大于了Survivor區(qū)域的大小,也大于了老年代可用內(nèi)存的大小。此時(shí)老年代都放不下這些存活對(duì)象了,就會(huì)發(fā)生Handle Promotion Failure的情況,這個(gè)時(shí)候就會(huì)觸發(fā)一次Full GC。


如果要是Full GC過后,老年代還是沒有足夠的空間存放Minor GC過后的剩余存活對(duì)象,那么此時(shí)就會(huì)導(dǎo)致所謂的“OOM”內(nèi)存溢出異常了。


這段規(guī)則有點(diǎn)繞,所以必須畫個(gè)圖梳理下:


一文詳解,jvm內(nèi)存分代與垃圾回收原理

圖5?空間擔(dān)保機(jī)制


另外需要注意的是,上面描述的空間擔(dān)保機(jī)制是jdk6以后的,與java6之前稍稍不同。


總結(jié)下,老年代觸發(fā)垃圾回收的時(shí)機(jī):


(1)Minor GC之前,發(fā)現(xiàn)很可能Minor GC之后要進(jìn)入老年代的對(duì)象太多了,老年代放不下,此時(shí)需要提前觸發(fā)Full GC然后再帶著進(jìn)行Minor GC;


(2)Minor GC之后,發(fā)現(xiàn)剩余對(duì)象太多,老年代都放不下了。


老年代回收,一般使用的標(biāo)記整理算法,首先標(biāo)記出來老年代當(dāng)前存活的對(duì)象。


接著會(huì)讓這些存活對(duì)象在內(nèi)存里進(jìn)行移動(dòng),把存活對(duì)象盡量都挪動(dòng)到一起去,讓存活對(duì)象緊湊的靠在一起,避免垃圾回收過后出現(xiàn)過多的內(nèi)存碎片,然后再一次性把垃圾對(duì)象都回收掉。


總結(jié):


老年代存活對(duì)象比較多,存活對(duì)象比較大,所以老年代垃圾回收算法的速度至少比新生代的垃圾回收算法的速度慢10倍。


如果系統(tǒng)頻繁出現(xiàn)老年代的Full GC垃圾回收,會(huì)導(dǎo)致系統(tǒng)性能被嚴(yán)重影響,出現(xiàn)頻繁卡頓的情況。


所以所謂JVM優(yōu)化,就是盡可能讓對(duì)象都在新生代里分配和回收,盡量別讓太多對(duì)象頻繁進(jìn)入老年代,避免頻繁對(duì)老年代進(jìn)行垃圾回收,同時(shí)給系統(tǒng)充足的內(nèi)存大小,避免新生代頻繁的進(jìn)行垃圾回收。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉