1. <tt id="5hhch"><source id="5hhch"></source></tt>
    1. <xmp id="5hhch"></xmp>

  2. <xmp id="5hhch"><rt id="5hhch"></rt></xmp>

    <rp id="5hhch"></rp>
        <dfn id="5hhch"></dfn>

      1. Java的內存劃分全解析

        時間:2024-08-02 02:13:41 JAVA認證 我要投稿
        • 相關推薦

        Java的內存劃分全解析

          Java把內存劃分成兩種:一種是棧內存,一種是堆內存。以下是小編整理的Java的內存劃分全解析,希望對大家有所幫助。

          棧內存

          存放對象:函數中基本類型的變量和對象的引用變量、靜態類方法

          特點:棧有一個很重要的特殊性,就是存在棧中的數據可以共享。假設我們同時定義:

          inta=3;

          intb=3;

          編譯器先處理inta=3;首先它會在棧中創建一個變量為a的引用,然后查找棧中是否有3這個值,如果沒找到,就將3存放進來,然后將a指向3。

          接著處理intb=3;在創建完b的引用變量后,因為在棧中已經有3這個值,便將b直接指向3。這樣,就出現了a與b同時均指向3的情況。

          堆內存

          存放對象:用來存放由new創建的對象和數組。

          特點:在堆中分配的內存,由Java虛擬機的自動垃圾回收器來管理。

          在堆中產生了一個數組或對象后,還可以在棧中定義一個特殊的變量,讓棧中這個變量的取值等于數組或對象在堆內存中的首地址,棧中的這個變量就成了數組或對象的引用變量。

          引用變量就相當于是為數組或對象起的一個名稱,以后就可以在程序中使用棧中的引用變量來訪問堆中的數組或對象。

          Q:static關鍵字,是一個修飾符,用于修飾成員(成員變量和成員函數),有什么特點

          A:1、想要實現對象中的共性數據的對象共享?梢詫⑦@個數據進行靜態修飾。

          2、被靜態修飾的成員,可以直接被類名所調用。也就是說,靜態的成員多了一種調用方式。類名.靜態方式。

          3、靜態隨著類的加載而加載。而且優先于對象存在。

          Java內存回收

          Java的內存分配和回收也主要在Java的堆上進行的,Java的堆中存儲了大量的對象實例,所以Java的堆也叫GC堆。

          下面主要說一下對于java堆的內存回收 。

          什么樣的內存可以回收

          判斷法1:引用計數

          方法:每有一個引用指向這個對象,那么這個對象的引用計數+1,反之,每有一個引用改變了指向,那么他原來指向的對象引用計數-1,當引用計數為0的時候,這個對象也就不可能被使用了那么就可以被回收了

          問題:可能會出現環狀的引用,導致不可能被使用的對象永遠不可能被回收

          示例:

          Class A {

          A a;

          Public static void main(String[] args){

          A gc1 = new A();

          A gc2 = new A();

          Gc1.a = gc2;

          Gc2.a = gc1;

          Gc1= null;

          Gc2 = null;

          }

          Gc1和gc2都被設置成null了,他們都應該被清理,但是因為gc1的a對象指向gc2,gc2的a對象指向gc1,導致他們的引用計數永遠為1,但是他們都永遠不可能被使用了,所以這種方法存在漏洞

          判斷2:可達性分析算法

          方法:從一個叫做GC ROOTS的節點出發,所有能夠到達的引用對象標記起來,直到走到完全沒有引用的地方為止,這樣從這個節點連起來的所有的點(引用鏈),構成的路線就是不可回收的,那么所有沒有被到達過的對象均可以被回收

          什么可以做GC ROOTS:虛擬機棧(棧幀中的本地變量表)中的引用的對象、方法區中類靜態屬性引用的對象、方法區中常量引用的對象、本地方法棧中JNI引用的對象

          這些對象的特點:不可變并且隨時可能被用到,生命周期長

          補充:可達性分析的算法,那么沒有在引用鏈上的對象都一定會被清理嗎?不一定。當運行可達性分析的算法之后,會對所有沒有在引用鏈上的對象進行一次標記和篩選,篩選的條件為:該對象覆蓋了finallize()方法(這個方法是GC的時候如果這個對象要被回收則執行的方法,但是在Thinking in java中不推薦用來處理收尾工作),并且這個方法沒有被執行過,那么就會把這個對象放到一個低優先級隊列中執行,也就是這個對象的最后搶救的機會,如果這個時候這個對象把自己和在引用鏈上的引用連了起來,那么他在執行完finallize方法之后,再次判斷時就不會被清理,否則會在第二次可達性判斷的時候直接清理(因為finallize已經執行過一次了),如果沒有覆蓋這個方法,那么對不起,再見

          回收算法介紹:

          回收算法1:標記清理(Mark——sweep)算法

          標記所有需要回收對象,然后將他們清理回收

          問題:會產生內存碎片

          優點:不需要暫停所有線程(Stop the world)

          回收算法2:復制

          標記后,將所有不需要回收的對象全部復制到一個空的內存中,然后清理剛剛使用的內存塊

          問題:浪費資源,會有一些內存堆無法被使用

          解決:用在新生代,新生代會有80%以上的對象經過一次GC就會死亡,因此采用Eden + Survivor * 2的辦法,Eden = 8 * Survivor大。℉otSpot默認),那么每次使用一個Eden + 一個Survivor,然后進行復制清理的時候,清理Eden + Survivor中,然后將可用的對象復制到空閑的Survivor中,然后全部清空前面的使用區,然后使用Eden 和復制到的Survivor

          又一個問題:如果Survivor不夠怎么辦?向老年代借空間,叫做分配擔保,不夠存放的對象會通過分配擔保進入老年代

          問題:需要 stop the world

          回收算法3:標記整理(Mark——compact)

          標記后,將可用內存向一側擺放,然后清理掉可用內存邊緣外部的所有內存區域

          優點:沒有內存碎片的問題

          問題:需要stop the world

          回收算法4:分代收集

          將堆分代(老年代、新生代),老年代采用標記整理、標記清理等方法,新生代采用復制方法。

          為什么:因為老年代大部分對象是可用的,因此如果采用復制算法,雖然沒有內存碎片,但是空間浪費大,而且大部分對象沒有變化,而在新生代使用復制算法,可以犧牲很小的內存空間就獲得較好的效率

          HotSpot中內存回收算法

          枚舉根節點(GC ROOTs)

          Java虛擬機采用準確式GC,有一個OOPmap來標記哪個位置有個對象,這樣在查找引用鏈的時候可以較快的找齊所有的引用鏈

          Safepoint

          在OOPmap的協助下,這個可以快速且準確的完成枚舉,但是問題就是導致這個oopmap變化的指令非常多,如果為每一條指令生成oopmap,那么會需要大量額外空間,因此采用在特定點的地方生成,這些點同時也是safepoint的點,那么當需要枚舉根節點的時候,就讓線程運行到這個地方再停止。

          一種方法:先停止所有線程,然后再讓沒有到安全點的線程自己跑到安全點再停下來,基本不適用,搶先試中斷

          另一種方法:主動式中斷,設置一個標記,在執行的時候去輪詢,而需要中斷的時候,直接將這個位置的內存設置不可達,那么線程就會進入一個自陷異常,就自己會中斷

        【Java的內存劃分全解析】相關文章:

        Java內存溢出的類型10-03

        客廳設計要點全解析07-21

        JAVA垃圾收集算法與內存泄露的解決方法12-04

        日本留學費用全解析10-05

        java命令行參數解析201608-12

        2017高考攝影藝考全解析01-07

        2017藝考動畫專業全解析01-07

        加拿大中學留學申請全解析09-10

        ERP人力資源管理全解析08-06

        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码

        1. <tt id="5hhch"><source id="5hhch"></source></tt>
          1. <xmp id="5hhch"></xmp>

        2. <xmp id="5hhch"><rt id="5hhch"></rt></xmp>

          <rp id="5hhch"></rp>
              <dfn id="5hhch"></dfn>