JVM堆內(nèi)存詳解

JVM堆內(nèi)存

一、JVM堆內(nèi)存劃分

java中最大的特點(diǎn)在于其具備良好的垃圾收集特性

GC是整個(gè)java之中最重要的安全保證

整個(gè)JVM中的GC的處理機(jī)制:對(duì)不需要的對(duì)象進(jìn)行標(biāo)記,而后進(jìn)行清除


在JDK1.8之后,將最初的永久帶內(nèi)存空間取消了,該圖為JDK1.8之前的內(nèi)存空間組成

取消永久代目的是為了將HotSpot于JRockit兩個(gè)虛擬機(jī)標(biāo)準(zhǔn)聯(lián)合為一個(gè)

在整個(gè)JVM堆內(nèi)存之中實(shí)際上將內(nèi)存分為了三部分

新生帶(年輕代):新對(duì)象和沒(méi)達(dá)到一定年齡的對(duì)象都在年輕代

老年代:被長(zhǎng)時(shí)間使用的對(duì)象,老年代的內(nèi)存空間應(yīng)該要比年輕代更大

元空間(JDK1.8之前叫永久代):像一些方法中的操作臨時(shí)對(duì)象等,JDK1.8之前是占用JVM內(nèi)存,JDK1.8之后直接使用物理內(nèi)存

二、GC流程

基本所有數(shù)據(jù)都會(huì)保存在JVM的堆內(nèi)存之中

對(duì)于整個(gè)的GC流程里面,最需要處理的事年輕代與老年代的內(nèi)存清理操作

元空間(永久代)都不在GC范圍內(nèi)

具體流程:

當(dāng)現(xiàn)在有一個(gè)新的對(duì)象產(chǎn)生,JVM需要為該對(duì)象進(jìn)行內(nèi)存空間的申請(qǐng)

先判斷Eden區(qū)是否有內(nèi)存空間,如果有,直接將新對(duì)象保存在Eden區(qū)

如果Eden區(qū)的內(nèi)存空間不足,會(huì)自動(dòng)執(zhí)行一個(gè)Minor GC操作,將Eden區(qū)的無(wú)用內(nèi)存空間進(jìn)行清理

清理Eden區(qū)之后繼續(xù)判斷Eden區(qū)內(nèi)存空間情況,如果充足,則將新對(duì)象直接保存在Eden區(qū)

如果執(zhí)行了Minor GC之后發(fā)現(xiàn)Eden區(qū)的內(nèi)存依然不足,那就判斷存活區(qū)的內(nèi)存空間,并將Eden區(qū)的部分活躍對(duì)象保存在存活區(qū)

活躍對(duì)象遷移到存活區(qū)后,繼續(xù)判斷Eden區(qū)內(nèi)存空間情況,如果充足,則將新對(duì)象直接保存在Eden區(qū)

如果存活區(qū)也沒(méi)有空間了,則繼續(xù)判斷老年區(qū),如果老年區(qū)充足,則將存活區(qū)的部分活躍對(duì)象保存在老年區(qū)

存活區(qū)的活躍對(duì)象遷移到老年區(qū)后,則將Eden區(qū)的部分活躍對(duì)象保存在存活區(qū)

活躍對(duì)象遷移到存活區(qū)后,繼續(xù)判斷Eden區(qū)內(nèi)存空間情況,如果充足,則將新對(duì)象直接保存在Eden區(qū)

如果老年區(qū)也滿了,這時(shí)候產(chǎn)生Major GC(Full GC)進(jìn)行老年區(qū)的內(nèi)存清理

如果老年區(qū)執(zhí)行了Major GC之后發(fā)現(xiàn)無(wú)法進(jìn)行對(duì)象保存,會(huì)產(chǎn)生OutOfMemoryError異常

三、堆內(nèi)存參數(shù)調(diào)整(調(diào)優(yōu)關(guān)鍵)

實(shí)際上每一塊子內(nèi)存區(qū)中都會(huì)存在有一部分的可變伸縮區(qū)

如果空間不足時(shí),則在可變范圍之內(nèi)擴(kuò)大內(nèi)存空間

當(dāng)一段時(shí)間后,內(nèi)存空間有余,再將可變空間進(jìn)行釋放

堆內(nèi)存空間調(diào)整參數(shù)

-Xms:設(shè)置初始分配大小,默認(rèn)為物理內(nèi)存的1/64

-Xmx:最大分配內(nèi)存,默認(rèn)為物理內(nèi)存的1/4

-XX:+PrintGCDetails:輸出詳細(xì)的GC處理日志

-XX:+PrintGCTimeStamps:輸出GC的時(shí)間戳信息

-XX:+PrintGCDateStamps:輸出GC的時(shí)間戳信息(以日期的形式)

-XX:+PrintHeapAtGC:在GC進(jìn)行處理的前后打印堆內(nèi)存信息

-Xloggc:(SavePath):設(shè)置日志信息保存文件

在堆內(nèi)存的調(diào)整策略中,基本上只要調(diào)整兩個(gè)參數(shù):-Xms和-Xmx

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • JVM架構(gòu) 當(dāng)一個(gè)程序啟動(dòng)之前,它的class會(huì)被類裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,845評(píng)論 0 7
  • 內(nèi)存溢出和內(nèi)存泄漏的區(qū)別 內(nèi)存溢出:out of memory,是指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的內(nèi)存空間供其使用,...
    Aimerwhy閱讀 806評(píng)論 0 1
  • 一、內(nèi)存結(jié)構(gòu) 1. 方法區(qū): 存放類的信息(名稱、修飾符等)、類中的靜態(tài)變量、類中final型常量、類中的Fiel...
    田老師的架構(gòu)人生閱讀 730評(píng)論 0 0
  • 濱州的初冬相比煙臺(tái)來(lái)的總是早一點(diǎn)。早上六七點(diǎn)鐘五六度的溫度在還沒(méi)有供暖的房間里總想蜷縮在被窩睡到天荒地老。特別是對(duì)...
    121_e1f7閱讀 599評(píng)論 1 1
  • 渚行 說(shuō)起父親,心中就不知道有很多的話要說(shuō),卻不知道從何說(shuō)起。一直以來(lái),想寫點(diǎn)什么,向父親表示敬意和愛(ài)意,總是因?yàn)?..
    渚行閱讀 455評(píng)論 0 0

友情鏈接更多精彩內(nèi)容