這篇文章主要講解了“JVM內(nèi)存模型與垃圾回收知識點(diǎn)整理”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“JVM內(nèi)存模型與垃圾回收知識點(diǎn)整理”吧!
在溫嶺等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計、做網(wǎng)站 網(wǎng)站設(shè)計制作按需定制設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,網(wǎng)絡(luò)營銷推廣,外貿(mào)網(wǎng)站制作,溫嶺網(wǎng)站建設(shè)費(fèi)用合理。
本文的主要內(nèi)容如下:
內(nèi)存模型
垃圾回收
這幾個存儲區(qū)最主要的就是棧區(qū)和堆區(qū),那么什么是棧什么是堆呢?說的簡單點(diǎn),棧里面存放的是基本的數(shù)據(jù)類型和引用,而堆里面則是存放各種對象實(shí)例的。
堆與棧分開設(shè)計是為什么呢?
棧存儲了處理邏輯、堆存儲了具體的數(shù)據(jù),這樣隔離設(shè)計更為清晰
堆與棧分離,使得堆可以被多個棧共享。
棧保存了上下文的信息,因此只能向上增長;而堆是動態(tài)分配
棧的大小可以通過-XSs設(shè)置,如果不足的話,會引起java.lang.StackOverflowError的異常
線程私有,生命周期與線程相同。每個方法執(zhí)行的時候都會創(chuàng)建一個棧幀(stack frame)用于存放 局部變量表、操作棧、動態(tài)鏈接、方法出口。
存放對象實(shí)例,所有的對象的內(nèi)存都在這里分配。垃圾回收主要就是作用于這里的。
堆得內(nèi)存由-Xms指定,默認(rèn)是物理內(nèi)存的1/64;最大的內(nèi)存由-Xmx指定,默認(rèn)是物理內(nèi)存的1/4。
默認(rèn)空余的堆內(nèi)存小于40%時,就會增大,直到-Xmx設(shè)置的內(nèi)存。具體的比例可以由-XX:MinHeapFreeRatio指定
空余的內(nèi)存大于70%時,就會減少內(nèi)存,直到-Xms設(shè)置的大小。具體由-XX:MaxHeapFreeRatio指定。
因此一般都建議把這兩個參數(shù)設(shè)置成一樣大,可以避免JVM在不斷調(diào)整大小。
這里記錄了線程執(zhí)行的字節(jié)碼的行號,在分支、循環(huán)、跳轉(zhuǎn)、異常、線程恢復(fù)等都依賴這個計數(shù)器。
類型信息、字段信息、方法信息、其他信息
總結(jié)
棧區(qū) | 線程私有,使用一段連續(xù)的內(nèi)存空間 | 存放局部變量表、操作棧、動態(tài)鏈接、方法出口 | -XSs | StackOverflowError OutOfMemoryError |
堆 | 線程共享,生命周期與虛擬機(jī)相同 | 保存對象實(shí)例 | -Xms -Xmx -Xmn | OutOfMemoryError |
程序計數(shù)器 | 線程私有、占用內(nèi)存小 | 字節(jié)碼行號 | 無 | 無 |
方法區(qū) | 線程共享 | 存儲類加載信息、常量、靜態(tài)變量等 | -XX:PermSize -XX:MaxPermSize | OutOfMemoryError |
有兩種方式,一種是引用計數(shù)(但是無法解決循環(huán)引用的問題);另一種就是可達(dá)性分析。
判斷對象可以回收的情況:
顯示的把某個引用置位NULL或者指向別的對象
局部引用指向的對象
弱引用關(guān)聯(lián)的對象
這種方法優(yōu)點(diǎn)就是減少停頓時間,但是缺點(diǎn)是會造成內(nèi)存碎片。
這種方法不涉及到對象的刪除,只是把可用的對象從一個地方拷貝到另一個地方,因此適合大量對象回收的場景,比如新生代的回收。
這種方法可以解決內(nèi)存碎片問題,但是會增加停頓時間。
最后的這種方法是前面幾種的合體,即目前JVM主要采取的一種方法,思想就是把JVM分成不同的區(qū)域。每種區(qū)域使用不同的垃圾回收方法。
上面可以看到堆分成三個區(qū)域:
新生代(Young Generation):用于存放新創(chuàng)建的對象,采用復(fù)制回收方法,如果在s0和s1之間復(fù)制一定次數(shù)后,轉(zhuǎn)移到年老代中。這里的垃圾回收叫做minor GC;
年老代(Old Generation):這些對象垃圾回收的頻率較低,采用的標(biāo)記整理方法,這里的垃圾回收叫做 major GC。
永久代(Permanent Generation):存放Java本身的一些數(shù)據(jù),當(dāng)類不再使用時,也會被回收。
這里可以詳細(xì)的說一下新生代復(fù)制回收的算法流程:
在新生代中,分為三個區(qū):Eden, from survivor, to survior。
當(dāng)觸發(fā)minor GC時,會先把Eden中存活的對象復(fù)制到to Survivor中;
然后再看from survivor,如果次數(shù)達(dá)到年老代的標(biāo)準(zhǔn),就復(fù)制到年老代中;如果沒有達(dá)到則復(fù)制到to survivor中,如果to survivor滿了,則復(fù)制到年老代中。
然后調(diào)換from survivor 和 to survivor的名字,保證每次to survivor都是空的等待對象復(fù)制到那里的。
這種收集器就是以單線程的方式收集,垃圾回收的時候其他線程也不能工作。
以多線程的方式進(jìn)行收集
大致的流程為:初始標(biāo)記--并發(fā)標(biāo)記--重新標(biāo)記--并發(fā)清除
大致的流程為:初始標(biāo)記--并發(fā)標(biāo)記--最終標(biāo)記--篩選回收
感謝各位的閱讀,以上就是“JVM內(nèi)存模型與垃圾回收知識點(diǎn)整理”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對JVM內(nèi)存模型與垃圾回收知識點(diǎn)整理這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!