<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # 圖示 ![](https://box.kancloud.cn/73daed62155bafdf28142a994429505e_879x515.png) 虛擬機棧是執行java的 本地方法棧是為虛擬機執行native的 1. Class Loader類加載器 2. Execution Engine執行引擎負責解釋命令,提交操作系統執行 3. Native Interface本地接口 4. Runtime data area 運行數據區 # Class Loader類加載器 負責加載class文件,class文件在文件開頭有特定的文件標識,并且ClassLoader只負責class文件的加載,至于他是否可以運行,則由Execution Engine決定 # Native Interface 本地接口的作用是融合不同的編程語言為java所用,他的初衷是融合c/c++程序,于是就在內存中專門開辟了一塊區域處理標記為native的代碼. 他的具體做法是Native Method Stack中登記native方法,在Execution Engine執行時加載native libraries 目前該方法使用的越來越少,除非是與硬件有關的應用,比如通過java程序驅動打印機,或者java系統管理生產設備,在企業級應用中已經少見 因為現在異構領域間的通信很發達,比如可以使用socket通信,也可以使用web service等等 # Method Area方法區 方法區是被所有線程共享,所有字段和方法字節碼,以及一些特殊方法如構造器,接口代碼也在此定義. 簡單的說,所有定義的方法信息都保存在該區域,**此區域屬于共享區間** **靜態變量+常量+類信息+運行時常量池存+即使編譯后的代碼在方法區中,實例變量存在堆內存中** * 類的版本 * 字段 * 方法 * 接口 方法區和永久代: jdk已經將GC擴展至方法區了. 這個區域也會發生OutOfMemoryError ## 運行時常量池 * **運行時常量池是方法區的一部分**,所以也是全局共享的。 * **其作用是存儲 Java 類文件常量池中的符號信息。** * **class 文件中存在常量池(非運行時常量池),其在編譯階段就已經確定;JVM 規范對 class 文件結構有著嚴格的規范,必須符合此規范的 class 文件才會被 JVM 認可和裝載。** * **運行時常量池**中保存著一些 class 文件中描述的符號引用,同時還會將這些符號引用所翻譯出來的直接引用存儲在**運行時常量池**中。 * **運行時常量池相對于 class 常量池一大特征就是其具有動態性,Java 規范并不要求常量只能在運行時才產生,也就是說運行時常量池中的內容并不全部來自 class 常量池,class 常量池并非運行時常量池的唯一數據輸入口;在運行時可以通過代碼生成常量并將其放入運行時常量池中。** * 同方法區一樣,當運行時常量池無法申請到新的內存時,將拋出 OutOfMemoryError 異常。 ~~~ //局部變量表 String s1 = "abc"; String s2 = "abc"; //堆中 String s3 = new String("abc"); System.out.println(s1 == s2); //true System.out.println(s1 == s3); //false //運行時常量池,運行時產生的 System.out.println(s1 == s3.intern()); //true ~~~ # PC Register 程序計數器 * 是一塊較小的內存區域,可以看做是當前線程所執行的字節碼的行號指示器 * 程序計數器處于線程獨占區 * 如果線程執行的是java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址.如果正在執行的是navicat方法這個可以忽略不計 * 這個區域是唯一沒有規定任何OutOfMemoryError的情況 每個線程都有一個程序計數器,就是一個指針,指向方法區中的方法字節碼(下一個將要指向的指令代碼), 由執行引擎讀取下一條指令,是一個非常小的內存空間,幾乎可以忽略不計 # 虛擬機棧 虛擬機棧是執行java的. **棧幀** 每個方法執行都會創建一個棧幀,伴隨方法從創建到執行完成. 用于存儲局部變量表,操作數棧,動態鏈接,方法出口等. **局部變量表** 存放編譯期可知的各種基本數據類型,引用類型,returnAddress類型. 局部變量表的內存空間在編譯期完成分配,當進入一個方法時,這個方法需要在棧分配多少內存是固定的,在方法運行期間是不會改變局部變量表的大小 ~~~ //局部變量表 String s1 = "abc"; String s2 = "abc"; //堆中 String s3 = new String("abc"); System.out.println(s1 == s2); //true System.out.println(s1 == s3); //false ~~~ # Native Method Stack本地方法棧 它的具體做法是Native Method Stack中登記native方法,在Execution Engine執行時加載native libraries # 元空間和永久代 永久代基本不用了,現在都是元空間 元空間的本質和永久代類似,都是對jvm規范中方法區的實現. 不過元空間與永久代之間最大的區別在于: 元空間并不在虛擬機中,而是使用本地內存. 因此,在默認情況下,元空間的大小僅受本地內存限制 # Stack棧 棧也叫棧內存,主管java程序的運行,是在線程創建時創建,它的生命周期是跟隨線程的生命周期,線程結束棧內存也就釋放,對于**棧來說不存在垃圾回收問題** 只要線程一結束該棧就over,生命周期和線程一致,是**線程私有的** 基本類型的變量和對象的引用變量都是在函數的棧內存中分配 ![](https://box.kancloud.cn/2bafe639edb84151fa56f9a9669686ac_908x804.png) ## 棧存儲什么? 棧幀中主要保存3類數據: 本地變量(Local Variables): 輸入參數和輸出參數以及方法內的變量; 棧操作(Operand Stack): 記錄出棧,入棧的操作 棧幀數據(Frame Data): 包括類文件,方法等 # Heap堆 一個JVM實例只存在一個堆內存,堆內存的大小是可以調節的. 類加載器讀取了類文件后,需要把類,方法,常變量放到堆內存中,保存所有引用類型的真實信息,以方便執行器執行,堆內存分為三部分 * Young Generation Space新生區 Young * Tenure generation space 養老區 Old * Permanent Space 永久存儲區 Perm 實際而言,方法區(Method Area)和堆一樣,是各個線程共享的內存區域,它用于存儲虛擬機加載的:類信息+普通常量+靜態變量+編譯器編譯后的代碼等等 **雖然JVM規范將方法區描述為堆的一個邏輯部分,但他還有一個別名叫Non-Heap(非堆),目的就是要和堆分開.** 對于HotSpot虛擬機,很多開發者習慣將方法區稱為永久代,當嚴格本質上說兩者不同,或者說使用永久代來實現方法區而已,永久代是方法區的一個實現,JDK1.7版本中,已經將原本放在永久代的字符串常量池移走,放到堆中.把永久代給刪除了,然后又創建個元空間,把字符串常量池又放進去了. 常量池是方法區的一部分,Class文件除了有類的版本,字段,方法,接口等描述信息外,還有一項信息就是常量池,這部分內容將在類加載后進入方法區的運行時常量池中存放 ![](https://box.kancloud.cn/caa8082ede97059005441e8dbdf71014_540x273.png) GC ![](https://img.kancloud.cn/e4/d4/e4d48051196c84a677898fdd943fbf35_1030x473.png) ## 堆內存示意圖 ![](https://box.kancloud.cn/b56048ae78a679b7b1c0736f09bf78e5_619x500.png) ## 新生區 新生區是類的誕生、成長、消亡的區域,一個類在這里產生,應用,最后被垃圾回收器收集,結束生命。 **新生區又分為兩部分: 伊甸區(Eden space)和幸存者區(Survivor pace) ,所有的類都是在伊甸區被new出來的。幸存區有兩個: 0區(Survivor 0 space)和1區(Survivor 1 space)** 當伊甸園的空間用完時,程序又需要創建對象,JVM的垃圾回收器將對伊甸園區進行垃圾回收(Minor GC) 將伊甸園區中的不再被其他對象所引用的對象進行銷毀。然后將伊甸園中的剩余對象移動到幸存 0區。 若幸存 0區也滿了,再對該區進行垃圾回收,然后移動到 1 區。那如果1 區也滿了呢? 再移動到養老區。 若養老區也滿了,那么這個時候將產生Major GC(FullGC),進行養老區的內存清理。 若養老區執行了Full GC之后發現依然無法進行對象的保存,就會產生OOM異常**OutOfMemoryError** 如果出現java.lang.OutOfMemoryError: Java heap space異常,說明Java虛擬機的堆內存不夠。原因有二: (1)Java虛擬機的堆內存設置不夠,可以通過參數-Xms、-Xmx來調整。 (2)代碼中創建了大量大對象,并且長時間不能被垃圾收集器收集(存在被引用)。 ----內存溢出;內存泄漏 ## 養老區 ???????? 養老區用于保存從新生區篩選出來的 JAVA 對象,一般池對象都在這個區域活躍 ## 永久區 永久存儲區是一個常駐內存區域,用于存放JDK自身所攜帶的 Class,Interface 的元數據,也就是說它存儲的是運行環境必須的類信息,**被裝載進此區域的數據是不會被垃圾回收器回收掉的,關閉 JVM 才會釋放此區域所占用的內存。** 如果出現java.lang.OutOfMemoryError: PermGen space,說明是Java虛擬機對永久代Perm內存設置不夠。一般出現這種情況,都是程序啟動需要加載大量的第三方jar包。例如:在一個Tomcat下部署了太多的應用。或者大量動態反射生成的類不斷被加載,最終導致Perm區被占滿。 Jdk1.6及之前: 常量池分配在永久代,1.6在方法區 Jdk1.7:有,但已經逐步“去永久代”,1.7在堆 Jdk1.8及之后: 無,1.8在元空間 ![](https://img.kancloud.cn/5e/a5/5ea5d119e45a110110220d922c592656_1522x588.png) # 寫屏障 如何確保新生代對象被老年代引用的時候不被gc?(查詢老年代對象來確認對新生代對象的引用避免誤回收) 機制:當老年代存活對象多時,每次minor gc查詢老年代所有對象影響gc效率(因為gc stop-the-world),所以在老年代有一個write barrier(寫屏障)來管理的card table(卡表),card table存放了所有老年代對象對新生代對象的引用。 所以每次minor gc通過查詢card table來避免查詢整個老年代,以此來提高gc性能。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看