主頁 > 軟體設計 > young GC 和 full GC分別是什么? 物件什么時候在堆疊上分配?物件進入老年代的機制是怎樣的?

young GC 和 full GC分別是什么? 物件什么時候在堆疊上分配?物件進入老年代的機制是怎樣的?

2021-07-25 08:07:28 軟體設計

很長時間沒有更新了,不是偷懶了,是偷偷學習了,我呢把我比較感興趣的部分,復述一遍,當然會有錯誤,并不是權威,希望大家指正,共同進步,

文章目錄

  • 前言
  • 一、物件在堆疊上分配
  • 二、物件在EDEN分配
  • 三、 minor GC 和 full GC
  • 四、 物件進入老年代
    • 3.1大物件直接進入老年代
    • 3.2長期存活的物件將進入老年代
    • 3.3物件動態年齡判斷
    • 3.4老年代空間分配擔保機制
  • 五、 物件頭


前言

其實整個JVM引數的調優,大體上就是圍繞著如何去減少垃圾回收的次數,盡可能地不要讓full GC發生,因為不管是哪一種垃圾收集器,都會有STW(Stop The Word)發生,就會影響用戶體驗,因此本次呢是先和大家一起學習下物件的分配規則,了解young GC 和 full GC分別是什么,有何種關系,以及物件進入老年代的一些機制等等,

一、物件在堆疊上分配

當創建出來的物件沒有被參考的時候就變成了垃圾,需要依靠GC進行回收,去釋放記憶體,如果物件數量較多的時候,會給GC帶來較大壓力,也間接影響了應用的性能,
為了減少臨時物件在堆內分配的數量,JVM通過逃逸分析確定該物件不會被外部訪問,如果不會逃逸可以將該物件在堆疊上分配記憶體,這樣該物件所占用的記憶體空間就可以隨堆疊幀出堆疊而銷毀,就減輕了垃圾回收的壓力,
物件逃逸分析: 就是分析物件動態作用域,當一個物件在方法中被定義后,它可能被外部方法所參考,則說明該物件會逃逸,不能讓它跟著堆疊幀一起銷毀,

成功逃逸:

public User getUser(){
        User u = new User();
        return u;
    }

User物件通過return傳出這個方法外,顯然這個物件的作用域范圍不確定,就得在堆上創建了,

逃逸失敗:

public User getUser(){
        User u = new User();
    }

可以確定當方法結束這個User物件就是無效物件了,對于這樣的物件可以將其分配在堆疊記憶體里,讓其在方法結束時跟隨堆疊記憶體一起被回收掉,
當然,這個功能是可配置的,不喜歡你可以不要,恨了你可以拋棄,
JVM對于這種情況可以通過開啟逃逸分析引數

(-XX:+DoEscapeAnalysis)

來優化物件記憶體分配位置,使其通過標量替換優先分配在堆疊上(堆疊上分配),JDK7之后默認開啟逃逸分析,關閉使用引數

( -XX:-DoEscapeAnalysis)

標量替換: 通過逃逸分析確定該物件不會被外部訪問,并且物件可以被進一步分解時,JVM不會創建該物件,而是將該物件成員變數分解若干個被這個方法使用的成員變數所代替,這些代替的成員變數在堆疊幀或暫存器上分配空間,這樣就不會因為沒有一大塊連續空間導致物件記憶體不夠分配,

開啟標量替換引數(**-XX:+EliminateAllocations**),JDK7之后默認開啟,

標量與聚合量: 標量即不可被進一步分解的量,而JAVA的基本資料型別就是標量(如:int,long等基本資料型別以及reference型別等),標量的對立就是可以被進一步分解的量,而這種量稱之為聚合量,而在JAVA中物件就是可以被進一步分解的聚合量,

二、物件在EDEN分配

有的人一定和我一樣,看到EDEN這個名詞就很陌生,這什么鬼,這什么東西,其實就是堆中給分配的一塊區域,前面說了物件分配在堆疊上,如果不被分配到堆疊上那就只能分配在堆里了,那么EDEN又是堆中的…的…區域,
在這里插入圖片描述
(媽的,…什么鬼?)
先請你看一下這張圖,這是堆中新生代的的區域,你也可以說是年輕代,對立面就是老年代了,簡單地理解一下,年輕代嘛,放年輕的物件(剛創建的物件),老年代就放創建比較久的物件,那么為什么要做這樣的區分? 這個后面3.2做出了解釋,下面會說到什么樣的算創建比較久的物件,或者說年齡比較大的物件,

那么,在新生代中,又分有EDEN區和兩個survivor區,Eden與Survivor區默認8:1:1,為什么是

因為新生代的物件幾乎都是朝生夕死的(創建完很快就沒用了),存活時間很短,所以JVM默認的8:1:1的比例是很合適的,讓eden區盡量的大,survivor區夠用即可,JVM默認有這個引數

-XX:+UseAdaptiveSizePolicy

(默認開啟),會導致這個8:1:1比例自動變化,如果不想這個比例有變化可以設定引數

-XX:-UseAdaptiveSizePolicy

三、 minor GC 和 full GC

minor GC: 當大量的物件被分配在eden區,eden區滿了年輕代就會觸發垃圾回收 - minor gc(,可能會有99%以上的物件成為垃圾被回收掉,剩余存活的物件會被挪到為空的那塊survivor區,下一次eden區滿了后又會觸發minor gc,把eden區和上一次用到的survivor區垃圾物件回收,把剩余存活的物件一次性挪動到另外一塊為空的survivor區,以此回圈,使得整個年輕代的空間可以重復使用,

full GC: 有沒有可能一個survivor區裝不下依然存活的物件,那么默認需要存活的物件超過survivor區的一半,就會將這些物件提前轉移到老年代,而老年代空間存滿之后發生的垃圾回收就叫做full GC

區域GC速度
年輕代minor GC
老年代full GC

其實JVM調優部分引數也是圍繞著一個問題,如何盡量減少提前送養老的事情發生,因為 minor gc 是比較快的多得多的一種垃圾回收,一直送到老年代的話,老年代滿了是需要full GC的,這是比較慢的,會影響性能,

四、 物件進入老年代

3.1大物件直接進入老年代

大物件就是需要大量連續記憶體空間的物件(比如:字串、陣列),
JVM引數

 -XX:PretenureSizeThreshold 

可以設定大物件的大小,如果物件超過設定大小會直接進入老年代,不會進入年輕代,這個引數只在 Serial 和 ParNew兩個收集器下有效,
比如設定JVM引數:

-XX:PretenureSizeThreshold=1000000 (單位是位元組) -XX:+UseSerialGC 

應該有人會問,為什么要直接進入老年代,剛才不還是說盡量減少物件提前送到老年代么?這怎么不等minor GC 就直接送進老年代了呢?
試想一下,如果好幾個大物件生成在年輕代,且在minor GC時,都還存在,大小一下子就超過了survivor區得一半,這樣就會帶著這幾個大物件以及其他存活得物件一起到老年代,顯然,如果提前把大塊頭送走,其他物件有可能不會超過一半就不用送到老年代了,

3.2長期存活的物件將進入老年代

虛擬機采用分代得思想分配記憶體,這種思想的目的是,有的物件存活比較久甚至永遠存在,這類物件每次參與GC的篩選等一系列操作,顯然也會占用一定的時間,所以這類物件放在老年代也省去了一直在復制到survivor區的動作可以提高性能,減少折騰,

那么記憶體回收時就必須能識別哪些物件應放在新生代,哪些物件應放在老年代中,為了做到這一點,虛擬機給每個物件一個物件年齡(Age)計數器,

如果物件在 Eden 出生并經過第一次 Minor GC 后仍然能夠存活并且能被 Survivor 容納的話,將被移動到 Survivor空間中,并將物件年齡設為1,物件在 Survivor 中每熬過一次 MinorGC,年齡就增加1歲,當它的年齡增加到一定程度(默認為15歲,CMS收集器默認6歲,不同的垃圾收集器會略微有點不同),就會被晉升到老年代中(想想我要65歲才能退休,太慘了吧,我可以也15歲退休嗎?),
物件晉升到老年代的年齡閾值,可以通過引數 來設定,

 -XX:MaxTenuringThreshold 

3.3物件動態年齡判斷

Survivor區域里現在有一批物件,年齡1+年齡2+年齡n的多個年齡物件總和超過了Survivor區域的50%,
這個百分比有引數可以指定

-XX:TargetSurvivorRatio

此時就會把年齡n(含)以上的物件都放入老年代
這個規則其實是希望那些可能是長期存活的物件,盡早進入老年代,這有什么好處呢,就不用一股腦,超過50%,就把年輕的老的全抓去養老院,這樣養老院也不會那么容易滿就不容易導致full GC的發生,

3.4老年代空間分配擔保機制

年輕代每次minor gc之前JVM都會計算下老年代剩余可用空間
如果這個可用空間小于年輕代里現有的所有物件大小之和(包括垃圾物件)
就會看老年代的可用記憶體大小,是否大于之前每一次minor gc后進入老年代的物件的平均大小,
如果上一步結果是小于或者之前說的引數沒有設定,那么就會觸發一次Full gc,對老年代和年輕代一起回收一次垃圾,
在這里插入圖片描述

如果回收完還是沒有足夠空間存放新的物件就會發生"OOM"
當然,如果minor gc之后剩余存活的需要挪動到老年代的物件大小還是大于老年代可用空間,那么也會觸發full gc,fullgc完之后如果還是沒有空間放minor gc之后的存活物件,則也會發生“OOM”
老年代空間分配擔保機制可以通過引數配置是否生效

-XX:-HandlePromotionFailure

(jdk1.8默認就設定了)

五、 物件頭

這里想給大家看一下物件頭的一張表,暫時只先看下這張圖里的這個分代年齡,也就是說每個物件前面都跟著頭部,去記錄它的狀態,我們前面提到的物件年齡就是它每經歷一次minor GC 分代年齡就會+1.這個物件頭的內容,我想,慢慢的在每次用到的時候介紹一點,會更容易接受吧,因此這一次就介紹這么個分代年齡好了,
在這里插入圖片描述

好了,我的筆記結束,下期再見!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/289901.html

標籤:其他

上一篇:5分鐘通過水痘事件來認識系統架構

下一篇:【零基礎必備】監督學習之K近鄰演算法三元預測分類

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more