<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JVM運(yùn)行時數(shù)據(jù)區(qū)、類加載器和GC算法!!!

          共 3465字,需瀏覽 7分鐘

           ·

          2021-03-11 01:35

          JVM簡介

          JVM是Java虛擬機(jī),存在于JRE中,即Java運(yùn)行時環(huán)境,JVM是運(yùn)行在操作系統(tǒng)上的程序,而我們的Java程序是運(yùn)行在JRE(JVM)之上的,操作系統(tǒng)是運(yùn)行在硬件之上的。

          在這里插入圖片描述

          我們所編寫的Java文件,首先會被編譯成class文件,然后通過類加載器進(jìn)行加載到JVM中,也就是我們的運(yùn)行時數(shù)據(jù)區(qū),核心有五部分組成,分別是,方法區(qū)、堆、虛擬機(jī)棧、本地方法棧、程序計數(shù)器。
          在這里插入圖片描述

          類加載器

          所謂類加載器,也就是將.class文件加載為Class模板,并可以通過new關(guān)鍵字創(chuàng)建實例對象,實例對象可以通過getClass方法獲取Class模板,Class模板可以通過getClassLoader方法獲取類加載器。

          在這里插入圖片描述

          其中這里的類加載器有三種,分別是啟動類(根)加載器(BootStrap Class Loader)、擴(kuò)展加載器()ExtClassLoader、應(yīng)用程序加載器(AppClassLoader),根據(jù)雙親委派機(jī)制,當(dāng)加載一個對象的時候,會從應(yīng)用程序加載器往上找,找到擴(kuò)展類加載器,然后再往上找,找到根加載器,如果根加載器無法加載,那么就會看看擴(kuò)展類加載器是否可以加載,如果也不可以那么就去應(yīng)用程序加載器加載,如果還不可以,就會報錯。

          我們一般自定義的類,都是被應(yīng)用程序加載器進(jìn)行加載,JDK自帶的類,一般都是通過根加載器進(jìn)行加載,下圖ext包下的類都是擴(kuò)展類加載器進(jìn)行加載的。
          在這里插入圖片描述

          本地方法棧

          本地方法棧主要是存儲被native關(guān)鍵字修飾的方法,該方法會調(diào)用本地方法接口(Java Native Interface JNI)本地方法接口會調(diào)用本地方法庫,其中這里面主要是一些C/C++程序。

          在這里插入圖片描述

          程序計數(shù)器

          程序計數(shù)器:程序計數(shù)器是線程私有的,每個線程都有一個程序計數(shù)器,是線程私有的,它可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。

          方法區(qū)

          方法區(qū):方法區(qū)是線程共享的,主要存儲靜態(tài)變量常量類型信息(構(gòu)造方法、接口的定義)常量池

          虛擬機(jī)棧

          當(dāng)我們的方法被調(diào)用的時候,就會進(jìn)棧,當(dāng)方法執(zhí)行結(jié)束的時候就會出棧,其中main方法是第一個進(jìn)棧的方法,當(dāng)然了,由于棧是先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),所以main方法是最后出棧的方法,即最后結(jié)束的方法。
          當(dāng)我們的main方法調(diào)用其他方法的時候,其他方法也會進(jìn)棧,如果其他方法也調(diào)用了其他方法,那么還會進(jìn)棧那,如果我們有死循環(huán)(或其他不當(dāng)操作)進(jìn)棧,那么就會出現(xiàn)Stack Overflow即棧溢出。下面模擬一個棧溢出

          package com.hzy;
          public class Main {
              public static void main(String[] args){
                  a();
              }
              public static void a() {
                  b();
              }
              public static void b() {
                  a();
              }
          }
          在這里插入圖片描述

          棧中主要存放:八大基本數(shù)據(jù)類型、對象的引用、實例方法

          當(dāng)類加載器加載了類之后,會把類、方法、常量、變量放到堆中,并保存引用類型所指的真實對象。

          在這里插入圖片描述

          當(dāng)某個對象使用完畢之后,會出棧,但是,所指向的對象會殘留在堆中,也就成為了垃圾。對于堆來說,又被細(xì)分為了三部分:新生區(qū)、老年區(qū)、元空間(JDK8以后永久區(qū)改名為元空間)。新生區(qū)又細(xì)分為:伊甸園區(qū)(Eden)、幸存0區(qū)、幸存1區(qū)。這樣分的目的也就是為了解決堆中的垃圾問題,GC垃圾回收機(jī)制就是,會對新生區(qū)進(jìn)行垃圾回收,沒有被回收的垃圾會進(jìn)入到幸存區(qū)(0區(qū)或1區(qū)),GC垃圾回收機(jī)制會對幸存區(qū)進(jìn)行回收,這種在新生區(qū)進(jìn)行垃圾回收的機(jī)制是輕量級,即輕GC,如果在幸存區(qū)也沒有被清理掉,那么就會進(jìn)入老年區(qū)(默認(rèn)是被清理了15次還沒死,就進(jìn)入老年區(qū)),對新生區(qū)和老年區(qū)都進(jìn)行垃圾回收的機(jī)制是重量級的,即重GC,會把所有的垃圾都清理一下,我們所聽說的垃圾回收機(jī)制,也就是對新生區(qū)和老年區(qū)進(jìn)行的回收
          如果我們的新生區(qū)和老年區(qū)都滿了,就會報一個Out Of Memory(OOM)內(nèi)存不足。下面模擬一個OOM


          package com.hzy;
          public class Main {
              public static void main(String[] args){
                  String s = "hello";
                  while (true) {
                      s += s;
                  }
              }
          }
          在這里插入圖片描述

          在這里插入圖片描述

          這里的元空間常駐在內(nèi)存中,主要是存放我們的Class對象,接口定義,常量池和Java運(yùn)行時的一些環(huán)境,這里不存在垃圾,虛擬機(jī)關(guān)閉時會被釋放內(nèi)存
          在這里插入圖片描述

          這里需要注意一下,我們的方法區(qū)就是在元空間的,其中常量池是在方法區(qū)中的,很多時候,我們習(xí)慣把方法區(qū)單獨提出來,有時稱方法區(qū)為非堆。


          GC算法

          如何判斷該對象是垃圾?
          引用計數(shù)法
          用一個標(biāo)識位去計數(shù)該對象被引用的次數(shù),被引用一次該標(biāo)識位的值就加1,當(dāng)該標(biāo)識位的值為0的時候就認(rèn)為該對象是垃圾。
          可達(dá)性分析法
          從GC Roots往下搜索,如果某個對象不可達(dá)(也就是不在任何一棵樹上),就認(rèn)為該對象及與之相連的對象為垃圾(5,6,7為垃圾)。

          在這里插入圖片描述

          GC主要是對新生區(qū)和老年區(qū)進(jìn)行回收
          標(biāo)記-清除算法
          標(biāo)記清除算法是最基礎(chǔ)的垃圾回收算法,主要包括兩步,標(biāo)記和清除,首先標(biāo)記處所有需要回收的對象,標(biāo)記之后,統(tǒng)一回收掉所有被標(biāo)記的對象,反過來也可以,標(biāo)記存活的對象,統(tǒng)一回收所有未標(biāo)記的對象。該算法進(jìn)行標(biāo)記清除后,會有大量不連續(xù)的內(nèi)存碎片。

          在這里插入圖片描述

          標(biāo)記-復(fù)制算法
          復(fù)制算法主要是對新生區(qū)進(jìn)行垃圾回收,其中新生區(qū)又包括:伊甸園區(qū),幸存0區(qū)和幸存1區(qū),其實這里的0區(qū)和1區(qū)又叫做from區(qū)和to區(qū),這里的from區(qū)和to區(qū)是動態(tài)的,當(dāng)進(jìn)行垃圾回收的時候,如果伊甸園區(qū)有殘余垃圾,from區(qū)也有殘余垃圾,那么會把這兩個區(qū)的垃圾都放到to區(qū),并把to區(qū)改名為from區(qū),目的是保證to區(qū)永遠(yuǎn)為空(誰空誰是to),方便把伊甸園區(qū)和from區(qū)的垃圾都放到to區(qū)。這樣一來就會有一個空閑的區(qū)域,導(dǎo)致空間浪費。
          在這里插入圖片描述

          標(biāo)記-整理算法
          即是對標(biāo)記清楚算法再次掃描,進(jìn)行空位填充,這樣一來,沒有了空余空間,但是多了一遍遍歷,更耗時(一般都是執(zhí)行多次標(biāo)記清除算法才執(zhí)行一次標(biāo)記壓縮算法)。
          在這里插入圖片描述

          總結(jié)
          對于GC垃圾回收算法適用場景:新生區(qū)用標(biāo)記-復(fù)制算法,老年區(qū)用標(biāo)記-整理算法
          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本在线高清 | 香蕉视频乱伦 | 欧美成人www | 人妻熟女一区二区三区APP下载 | 操屄软件 |