1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      JVM對象創(chuàng)建和內(nèi)存分配原理解析

      創(chuàng)建對象

      專注于為中小企業(yè)提供成都網(wǎng)站制作、網(wǎng)站設(shè)計服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)立山免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。

      當(dāng) JVM 收到一個 new 指令時,會檢查指令中的參數(shù)在常量池是否有這個符號的引用,還會檢查該類是否已經(jīng)被加載過了,如果沒有的話則要進(jìn)行一次類加載。

      接著就是分配內(nèi)存了,通常有兩種方式:

      • 指針碰撞
      • 空閑列表

      使用指針碰撞的前提是堆內(nèi)存是完全工整的,用過的內(nèi)存和沒用的內(nèi)存各在一邊每次分配的時候只需要將指針向空閑內(nèi)存一方移動一段和內(nèi)存大小相等區(qū)域即可。

      當(dāng)堆中已經(jīng)使用的內(nèi)存和未使用的內(nèi)存互相交錯時,指針碰撞的方式就行不通了,這時就需要采用空閑列表的方式。虛擬機會維護(hù)一個空閑的列表,用于記錄哪些內(nèi)存是可以進(jìn)行分配的,分配時直接從可用內(nèi)存中直接分配即可。

      堆中的內(nèi)存是否工整是有垃圾收集器來決定的,如果帶有壓縮功能的垃圾收集器就是采用指針碰撞的方式來進(jìn)行內(nèi)存分配的。

      分配內(nèi)存時也會出現(xiàn)并發(fā)問題:

      這樣可以在創(chuàng)建對象的時候使用 CAS 這樣的樂觀鎖來保證。

      也可以將內(nèi)存分配安排在每個線程獨有的空間進(jìn)行,每個線程首先在堆內(nèi)存中分配一小塊內(nèi)存,稱為本地分配緩存(TLAB : Thread Local Allocation Buffer)。

      分配內(nèi)存時,只需要在自己的分配緩存中分配即可,由于這個內(nèi)存區(qū)域是線程私有的,所以不會出現(xiàn)并發(fā)問題。

      可以使用 -XX:+/-UseTLAB 參數(shù)來設(shè)定 JVM 是否開啟 TLAB 。

      內(nèi)存分配之后需要對該對象進(jìn)行設(shè)置,如對象頭。對象頭的一些應(yīng)用可以查看 Synchronize 關(guān)鍵字原理。

      對象訪問

      一個對象被創(chuàng)建之后自然是為了使用,在 Java 中是通過棧來引用堆內(nèi)存中的對象來進(jìn)行操作的。

      對于我們常用的 HotSpot 虛擬機來說,這樣引用關(guān)系是通過直接指針來關(guān)聯(lián)的。

      這樣的好處就是:在 Java 里進(jìn)行頻繁的對象訪問可以提升訪問速度(相對于使用句柄池來說)。

      內(nèi)存分配

      Eden 區(qū)分配

      簡單的來說對象都是在堆內(nèi)存中分配的,往細(xì)一點看則是優(yōu)先在 Eden 區(qū)分配。

      這里就涉及到堆內(nèi)存的劃分了,為了方便垃圾回收,JVM 將對內(nèi)存分為新生代和老年代。

      而新生代中又會劃分為 Eden 區(qū),from Survivor、to Survivor 區(qū)。

      其中 Eden 和 Survivor 區(qū)的比例默認(rèn)是 8:1:1,當(dāng)然也支持參數(shù)調(diào)整 -XX:SurvivorRatio=8。

      當(dāng)在 Eden 區(qū)分配內(nèi)存不足時,則會發(fā)生 minorGC ,由于 Java 對象多數(shù)是朝生夕滅的特性,所以 minorGC 通常會比較頻繁,效率也比較高。

      當(dāng)發(fā)生 minorGC 時,JVM 會根據(jù)復(fù)制算法將存活的對象拷貝到另一個未使用的 Survivor 區(qū),如果 Survivor 區(qū)內(nèi)存不足時,則會使用分配擔(dān)保策略將對象移動到老年代中。

      談到 minorGC 時,就不得不提到 fullGC(majorGC) ,這是指發(fā)生在老年代的 GC ,不論是效率還是速度都比 minorGC 慢的多,回收時還會發(fā)生 stop the world 使程序發(fā)生停頓,所以應(yīng)當(dāng)盡量避免發(fā)生 fullGC 。

      老年代分配

      也有一些情況會導(dǎo)致對象直接在老年代分配,比如當(dāng)分配一個大對象時(大的數(shù)組,很長的字符串),由于 Eden 區(qū)沒有足夠大的連續(xù)空間來分配時,會導(dǎo)致提前觸發(fā)一次 GC,所以盡量別頻繁的創(chuàng)建大對象。

      因此 JVM 會根據(jù)一個閾值來判斷大于該閾值對象直接分配到老年代,這樣可以避免在新生代頻繁的發(fā)生 GC。

      對于一些在新生代的老對象 JVM 也會根據(jù)某種機制移動到老年代中。

      JVM 是根據(jù)記錄對象年齡的方式來判斷該對象是否應(yīng)該移動到老年代,根據(jù)新生代的復(fù)制算法,當(dāng)一個對象被移動到 Survivor 區(qū)之后 JVM 就給該對象的年齡記為1,每當(dāng)熬過一次 minorGC 后對象的年齡就 +1 ,直到達(dá)到閾值(默認(rèn)為15)就移動到老年代中。

      可以使用 -XX:MaxTenuringThreshold=15 來配置這個閾值。

      總結(jié)

      雖說這些內(nèi)容略顯枯燥,但當(dāng)應(yīng)用發(fā)生不正常的 GC 時,可以方便更快的定位問題。

      以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。


      標(biāo)題名稱:JVM對象創(chuàng)建和內(nèi)存分配原理解析
      當(dāng)前網(wǎng)址:http://www.ef60e0e.cn/article/jppcpc.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        浮梁县| 海南省| 惠水县| 靖宇县| 平陆县| 晋宁县| 米林县| 佳木斯市| 扶风县| 乌兰察布市| 湄潭县| 敖汉旗| 中西区| 玉田县| 茶陵县| 固安县| 申扎县| 辽阳县| 南安市| 万安县| 盐池县| 白玉县| 青阳县| 东辽县| 通渭县| 荃湾区| 保亭| 澎湖县| 涿鹿县| 蒙阴县| 宜君县| 华坪县| 抚顺县| 昌都县| 绍兴市| 岳阳市| 平顺县| 泸西县| 沂水县| 宕昌县| 手机|