JAVA運(yùn)行時(shí)內(nèi)存及垃圾回收

JAVA

1. Java運(yùn)行時(shí)內(nèi)存區(qū)域

在JAVA運(yùn)行時(shí)的內(nèi)存區(qū)域中驶乾,由JVM管理的內(nèi)存區(qū)域分為以下幾個(gè)模塊:

  • 程序計(jì)數(shù)區(qū):由當(dāng)前線程獨(dú)占惰爬,記錄當(dāng)前線程的字節(jié)碼文件執(zhí)行到哪一行。
  • 虛擬機(jī)棧:由當(dāng)前線程獨(dú)占辜王,存放當(dāng)前線程調(diào)用方法的棧幀的棧劈狐。
  • 本地方法棧:由當(dāng)前線程獨(dú)占,和虛擬機(jī)棧類似呐馆, 只不過虛擬機(jī)棧記錄的是JAVA方法肥缔,本地方法棧記錄的是native方法。
  • 堆:由所有線程共享汹来,存放對(duì)象實(shí)例续膳。
  • 方法區(qū):由所有線程共享,存儲(chǔ)已經(jīng)被虛擬機(jī)加載的類信息俗慈,final常量姑宽,靜態(tài)變量,編譯器即時(shí)編譯的代碼等闺阱。

棧幀補(bǔ)充:每一個(gè)線程都有一個(gè)虛擬機(jī)棧炮车,每當(dāng)線程中執(zhí)行一個(gè)方法的時(shí)候,就會(huì)向虛擬機(jī)棧中插入一個(gè)棧幀酣溃,當(dāng)方法執(zhí)行完后瘦穆,再將棧幀出棧。棧幀中包含局部變量表赊豌,操作站扛或,方法出口等。
局部變量表中存儲(chǔ)著方法相關(guān)的局部變量碘饼,包括基本數(shù)據(jù)類型熙兔,對(duì)象的引用,返回地址等艾恼。
具體請(qǐng)參考Java內(nèi)存區(qū)域與內(nèi)存溢出

方法區(qū)補(bǔ)充:方法區(qū)屬于垃圾回收機(jī)制中的永久代(一共有青年帶住涉,老年代,永久代三種)钠绍,因此方法區(qū)的垃圾回收很少舆声,但不代表不會(huì)發(fā)生垃圾回收,其上的垃圾回收主要針對(duì)常量池的內(nèi)存回收和對(duì)已加載類的卸載柳爽。

2. JAVA對(duì)象的訪問方式

一般來說媳握,一個(gè)JAVA引用至少會(huì)涉及到三個(gè)內(nèi)存區(qū)域,虛擬機(jī)棧磷脯、堆蛾找、方法區(qū)。
例如 Object obj = new Object();

  • Object obj表示一個(gè)本地引用赵誓,存儲(chǔ)在虛擬機(jī)棧的本地變量表中
  • new Object()作為實(shí)例對(duì)象存放在堆中
  • 堆中還存儲(chǔ)了Object類的類型信息(接口腋粥,方法晦雨,field,對(duì)象類型等)的地址隘冲,這些地址所指向的內(nèi)容存放在方法區(qū)中
3. JAVA內(nèi)存分配及回收機(jī)制

分代分配闹瞧,分代回收。
JAVA內(nèi)存分為年輕代展辞、老年代奥邮、永久代

  • 年輕代:對(duì)象被創(chuàng)建時(shí),內(nèi)存分配首先創(chuàng)建在年輕代的Eden區(qū)(如果年輕代空間不足罗珍,則大對(duì)象直接分配在老年代上)洽腺。大部分對(duì)象很快就不再使用。年輕代的內(nèi)存區(qū)域分為:一個(gè)Eden區(qū)和兩個(gè)Survivor區(qū)(比例為8:1:1)
  • 老年代:對(duì)象如果在年輕代存活了很長(zhǎng)時(shí)間沒有被回收掉覆旱,就會(huì)被復(fù)制到老年代蘸朋。老年代的空間比年輕代大,發(fā)生的GC次數(shù)也比年輕代少扣唱。
  • 永久代:方法區(qū)屬于永久代藕坯,永久代的垃圾回收次數(shù)很少,但是也會(huì)發(fā)生GC噪沙。

GC分為兩種:

  • Minor GC
    只會(huì)在年輕代的Eden區(qū)進(jìn)行垃圾回收
  • FULL GC
    會(huì)在年輕代, 老年代, 永久帶都進(jìn)行垃圾回收
    有如下原因可能導(dǎo)致Full GC:
    1.年老代(Tenured)被寫滿;
    2.持久代(Perm)被寫滿;
    3.System.gc()被顯示調(diào)用;
    4.上一次GC之后Heap的各域分配策略動(dòng)態(tài)變化.

GC機(jī)制:

  • 年輕代:主要使用“停止-復(fù)制”算法炼彪,停止指的是,發(fā)生GC的時(shí)候會(huì)暫停除了GC線程以外的所有線程的運(yùn)行正歼。
    復(fù)制的過程如下:
    1. 絕大部分的對(duì)象剛創(chuàng)建的時(shí)候會(huì)被分配到Eden區(qū)辐马,其中大部分的對(duì)象會(huì)很快消亡。Eden區(qū)是連續(xù)的內(nèi)存空間局义,因此在其上分配內(nèi)存是很快的喜爷。
    2. 最初一次,當(dāng)Eden區(qū)滿的時(shí)候萄唇,執(zhí)行Minor GC贞奋,將Eden區(qū)的消亡對(duì)象清除掉,并將剩余的對(duì)象放到Survivor1中(此時(shí)Survivor2是空的穷绵,兩個(gè)Survivor總有一個(gè)是空的)
    3. 下次Eden再滿的時(shí)候,執(zhí)行Minor GC特愿,將Eden區(qū)的消亡對(duì)象清除掉仲墨,將剩余的對(duì)象放到Survivor1中
    4. 當(dāng)Survivor1滿了的時(shí)候則將Eden和Survivor1中的消亡的對(duì)象清除掉,并將Eden和Survivor1中剩余的對(duì)象復(fù)制到Survivor2中
    5. 當(dāng)兩個(gè)Survivor交換了幾次后揍障,就可以將剩下的對(duì)象復(fù)制到老年代中了
  • 老年代:使用“標(biāo)記-整理”算法目养,即將存活的對(duì)象向一邊移動(dòng),以此來保證回收后毒嫡,內(nèi)存依然是連續(xù)的癌蚁,不會(huì)出現(xiàn)內(nèi)存碎片幻梯。每次年輕代的Eden發(fā)生Minor GC時(shí),虛擬機(jī)都會(huì)檢查每次晉級(jí)老年代的大小是否大于老年代的剩余大小努释,如果大于則會(huì)觸發(fā)FULL GC碘梢。
  • 永久代:永久代的回收有兩種,常量池中的常量伐蒂,無用的類的信息煞躬。
    常量沒有引用了就可以回收。
    無用的類必須保證3點(diǎn)才可以回收:
    1. 類的所有實(shí)例已經(jīng)被回收
    2. 加載類的ClassLoader已經(jīng)被回收
    3. 類對(duì)象的class對(duì)象沒有被引用(即沒有反射調(diào)用該類的地方)
4. 減少GC開銷的措施

根據(jù)上述GC的機(jī)制,程序的運(yùn)行會(huì)直接影響系統(tǒng)環(huán)境的變化,從而影響GC的觸發(fā)逸邦。若不針對(duì)GC的特點(diǎn)進(jìn)行設(shè)計(jì)和編碼,就會(huì)出現(xiàn)內(nèi)存駐留等一系列負(fù)面影響恩沛。為了避免這些影響,基本的原則就是盡可能地減少垃圾和減少GC過程中的開銷。具體措施包括以下幾個(gè)方面:

  • 不要顯式調(diào)用System.gc()
    此函數(shù)建議JVM進(jìn)行主GC,雖然只是建議而非一定,但很多情況下它會(huì)觸發(fā)主GC,從而增加主GC的頻率,也即增加了間歇性停頓的次數(shù)缕减。

  • 盡量減少臨時(shí)對(duì)象的使用
    臨時(shí)對(duì)象在跳出函數(shù)調(diào)用后,會(huì)成為垃圾,少用臨時(shí)變量就相當(dāng)于減少了垃圾的產(chǎn)生,從而延長(zhǎng)了出現(xiàn)上述第二個(gè)觸發(fā)條件出現(xiàn)的時(shí)間,減少了主GC的機(jī)會(huì)雷客。

  • 對(duì)象不用時(shí)最好顯式置為Null
    一般而言,為Null的對(duì)象都會(huì)被作為垃圾處理,所以將不用的對(duì)象顯式地設(shè)為Null,有利于GC收集器判定垃圾,從而提高了GC的效率。

  • 盡量使用StringBuffer,而不用String來累加字符串
    由于String是固定長(zhǎng)的字符串對(duì)象,累加String對(duì)象時(shí),并非在一個(gè)String對(duì)象中擴(kuò)增,而是重新創(chuàng)建新的String對(duì)象,如Str5=Str1+Str2+Str3+Str4,這條語句執(zhí)行過程中會(huì)產(chǎn)生多個(gè)垃圾對(duì)象,因?yàn)閷?duì)次作“+”操作時(shí)都必須創(chuàng)建新的String對(duì)象,但這些過渡對(duì)象對(duì)系統(tǒng)來說是沒有實(shí)際意義的,只會(huì)增加更多的垃圾桥狡。避免這種情況可以改用StringBuffer來累加字符串,因StringBuffer是可變長(zhǎng)的,它在原有基礎(chǔ)上進(jìn)行擴(kuò)增,不會(huì)產(chǎn)生中間對(duì)象搅裙。

  • 能用基本類型如Int,Long,就不用Integer,Long對(duì)象
    基本類型變量占用的內(nèi)存資源比相應(yīng)對(duì)象占用的少得多,如果沒有必要,最好使用基本變量。

  • 盡量少用靜態(tài)對(duì)象變量
    靜態(tài)變量屬于全局變量,不會(huì)被GC回收,它們會(huì)一直占用內(nèi)存总放。

  • 分散對(duì)象創(chuàng)建或刪除的時(shí)間
    集中在短時(shí)間內(nèi)大量創(chuàng)建新對(duì)象,特別是大對(duì)象,會(huì)導(dǎo)致突然需要大量?jī)?nèi)存,JVM在面臨這種情況時(shí),只能進(jìn)行主GC,以回收內(nèi)存或整合內(nèi)存碎片,從而增加主GC的頻率呈宇。集中刪除對(duì)象,道理也是一樣的。它使得突然出現(xiàn)了大量的垃圾對(duì)象,空閑空間必然減少,從而大大增加了下一次創(chuàng)建新對(duì)象時(shí)強(qiáng)制主GC的機(jī)會(huì)局雄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末甥啄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子炬搭,更是在濱河造成了極大的恐慌蜈漓,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宫盔,死亡現(xiàn)場(chǎng)離奇詭異融虽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)灼芭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門有额,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彼绷,你說我怎么就攤上這事巍佑。” “怎么了寄悯?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵萤衰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我猜旬,道長(zhǎng)脆栋,這世上最難降的妖魔是什么倦卖? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮椿争,結(jié)果婚禮上怕膛,老公的妹妹穿的比我還像新娘。我一直安慰自己丘薛,他們只是感情好嘉竟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著洋侨,像睡著了一般舍扰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上希坚,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天边苹,我揣著相機(jī)與錄音,去河邊找鬼裁僧。 笑死个束,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的聊疲。 我是一名探鬼主播茬底,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼获洲!你這毒婦竟也來了阱表?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤贡珊,失蹤者是張志新(化名)和其女友劉穎最爬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體门岔,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爱致,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寒随。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糠悯。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖妻往,靈堂內(nèi)的尸體忽然破棺而出互艾,到底是詐尸還是另有隱情,我是刑警寧澤蒲讯,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站灰署,受9級(jí)特大地震影響判帮,放射性物質(zhì)發(fā)生泄漏局嘁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一晦墙、第九天 我趴在偏房一處隱蔽的房頂上張望悦昵。 院中可真熱鬧,春花似錦晌畅、人聲如沸但指。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)棋凳。三九已至,卻和暖如春连躏,著一層夾襖步出監(jiān)牢的瞬間剩岳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工入热, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拍棕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓勺良,卻偏偏與公主長(zhǎng)得像绰播,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尚困,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容