日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

36.JVM内存分哪几个区,每个区的作用是什么、如和判断一个对象是否存活、java垃圾回收机制、垃圾收集的方法有哪些、java类加载过程、类加载机制、双亲委派、Minor GC和Major GC

發布時間:2024/9/27 编程问答 31 豆豆

36.JVM內存分哪幾個區,每個區的作用是什么?
37.如和判斷一個對象是否存活?(或者GC對象的判定方法)
38.簡述java垃圾回收機制?
39.java中垃圾收集的方法有哪些?
40.java類加載過程?
41.簡述java類加載機制?
42.類加載器雙親委派模型機制?
43.什么是類加載器,類加載器有哪些?
44.簡述java內存分配與回收策率以及Minor GC和Major GC

36.JVM內存分哪幾個區,每個區的作用是什么?

Java虛擬機主要分為以下一個區:
方法區:

  • 有時候也成為永久代,在該區內很少發生垃圾回收,但是并不代表不發生GC,在這里進行的GC主要是對方法區里的常量池和對類型的卸載
  • 方法區主要用來存儲已被虛擬機加載的類的信息、常量、靜態變量和即時編譯器編譯后的代碼等數據。
  • 該區域是被線程共享的。
  • 方法區里有一個運行時常量池,用于存放靜態編譯產生的字面量和符號引用。該常量池具有動態性,也就是說常量并不一定是編譯時確定,運行時生成的常量也會存在這個常量池中。
  • 虛擬機棧:

  • 虛擬機棧也就是我們平常所稱的棧內存,它為java方法服務,每個方法在執行的時候都會創建一個棧幀,用于存儲局部變量表、操作數棧、動態鏈接和方法出口等信息。
  • 虛擬機棧是線程私有的,它的生命周期與線程相同。
  • 局部變量表里存儲的是基本數據類型、returnAddress類型(指向一條字節碼指令的地址)和對象引用,這個對象引用有可能是指向對象起始地址的一個指針,也有可能是代表對象的句柄或者與對象相關聯的位置。局部變量所需的內存空間在編譯器間確定
    4.操作數棧的作用主要用來存儲運算結果以及運算的操作數,它不同于局部變量表通過索引來訪問,而是壓棧和出棧的方式
    5.每個棧幀都包含一個指向運行時常量池中該棧幀所屬方法的引用,持有這個引用是為了支持方法調用過程中的動態連接.動態鏈接就是將常量池中的符號引用在運行期轉化為直接引用。
    本地方法棧
    本地方法棧和虛擬機棧類似,只不過本地方法棧為Native方法服務。

    java堆是所有線程所共享的一塊內存,在虛擬機啟動時創建,幾乎所有的對象實例都在這里創建,因此該區域經常發生垃圾回收操作。
    程序計數器
    內存空間小,字節碼解釋器工作時通過改變這個計數值可以選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理和線程恢復等功能都需要依賴這個計數器完成。該內存區域是唯一一個java虛擬機規范沒有規定任何OOM情況的區域。
  • 37.如和判斷一個對象是否存活?(或者GC對象的判定方法)

    判斷一個對象是否存活有兩種方法:
    1. 引用計數法
    所謂引用計數法就是給每一個對象設置一個引用計數器,每當有一個地方引用這個對象時,就將計數器加一,引用失效時,計數器就減一。當一個對象的引用計數器為零時,說明此對象沒有被引用,也就是“死對象”,將會被垃圾回收.
    引用計數法有一個缺陷就是無法解決循環引用問題,也就是說當對象A引用對象B,對象B又引用者對象A,那么此時A,B對象的引用計數器都不為零,也就造成無法完成垃圾回收,所以主流的虛擬機都沒有采用這種算法。

    2.可達性算法(引用鏈法)
    該算法的思想是:從一個被稱為GC Roots的對象開始向下搜索,如果一個對象到GC Roots沒有任何引用鏈相連時,則說明此對象不可用。
    在java中可以作為GC Roots的對象有以下幾種:
    ?虛擬機棧中引用的對象
    ?方法區類靜態屬性引用的對象
    ?方法區常量池引用的對象
    ?本地方法棧JNI引用的對象

    雖然這些算法可以判定一個對象是否能被回收,但是當滿足上述條件時,一個對象比不一定會被回收。當一個對象不可達GC Root時,這個對象并不會立馬被回收,而是出于一個死緩的階段,若要被真正的回收需要經歷兩次標記
    如果對象在可達性分析中沒有與GC Root的引用鏈,那么此時就會被第一次標記并且進行一次篩選,篩選的條件是是否有必要執行finalize()方法。當對象沒有覆蓋finalize()方法或者已被虛擬機調用過,那么就認為是沒必要的。
    如果該對象有必要執行finalize()方法,那么這個對象將會放在一個稱為F-Queue的對隊列中,虛擬機會觸發一個Finalize()線程去執行,此線程是低優先級的,并且虛擬機不會承諾一直等待它運行完,這是因為如果finalize()執行緩慢或者發生了死鎖,那么就會造成F-Queue隊列一直等待,造成了內存回收系統的崩潰。GC對處于F-Queue中的對象進行第二次被標記,這時,該對象將被移除”即將回收”集合,等待回收。

    38.簡述java垃圾回收機制?

    在java中,程序員是不需要顯示的去釋放一個對象的內存的,而是由虛擬機自行執行。在JVM中,有一個垃圾回收線程,它是低優先級的,在正常情況下是不會執行的,只有在虛擬機空閑或者當前堆內存不足時,才會觸發執行,掃描那些沒有被任何引用的對象,并將它們添加到要回收的集合中,進行回收。

    39.java中垃圾收集的方法有哪些?

    1.標記-清除:
    這是垃圾收集算法中最基礎的,根據名字就可以知道,它的思想就是標記哪些要被回收的對象,然后統一回收。這種方法很簡單,但是會有兩個主要問題:1.效率不高,標記和清除的效率都很低;2.會產生大量不連續的內存碎片,導致以后程序在分配較大的對象時,由于沒有充足的連續內存而提前觸發一次GC動作。
    2.復制算法:
    為了解決效率問題,復制算法將可用內存按容量劃分為相等的兩部分,然后每次只使用其中的一塊,當一塊內存用完時,就將還存活的對象復制到第二塊內存上,然后一次性清楚完第一塊內存,再將第二塊上的對象復制到第一塊。但是這種方式,內存的代價太高,每次基本上都要浪費一般的內存。
    于是將該算法進行了改進,內存區域不再是按照1:1去劃分,而是將內存劃分為8:1:1三部分,較大那份內存交Eden區,其余是兩塊較小的內存區叫Survior區。每次都會優先使用Eden區,若Eden區滿,就將對象復制到第二塊內存區上,然后清除Eden區,如果此時存活的對象太多,以至于Survivor不夠時,會將這些對象通過分配擔保機制復制到老年代中。(java堆又分為新生代和老年代)
    3.標記-整理
    該算法主要是為了解決標記-清除,產生大量內存碎片的問題;當對象存活率較高時,也解決了復制算法的效率問題。它的不同之處就是在清除對象的時候現將可回收對象移動到一端,然后清除掉端邊界以外的對象,這樣就不會產生內存碎片了。
    4.分代收集
    現在的虛擬機垃圾收集大多采用這種方式,它根據對象的生存周期,將堆分為新生代和老年代。在新生代中,由于對象生存期短,每次回收都會有大量對象死去,那么這時就采用復制算法。老年代里的對象存活率較高,沒有額外的空間進行分配擔保,所以可以使用標記-整理 或者 標記-清除。

    40.java類加載過程?

    java類加載需要經歷一下7個過程:
    加載
    加載時類加載的第一個過程,在這個階段,將完成一下三件事情:

  • 通過一個類的全限定名獲取該類的二進制流。
  • 將該二進制流中的靜態存儲結構轉化為方法去運行時數據結構。
  • 在內存中生成該類的Class對象,作為該類的數據訪問入口。
    驗證
    驗證的目的是為了確保Class文件的字節流中的信息不會危害到虛擬機.在該階段主要完成以下四鐘驗證:
  • 文件格式驗證:驗證字節流是否符合Class文件的規范,如主次版本號是否在當前虛擬機范圍內,常量池中的常量是否有不被支持的類型.
  • 元數據驗證:對字節碼描述的信息進行語義分析,如這個類是否有父類,是否集成了不被繼承的類等。
  • 字節碼驗證:是整個驗證過程中最復雜的一個階段,通過驗證數據流和控制流的分析,確定程序語義是否正確,主要針對方法體的驗證。如:方法中的類型轉換是否正確,跳轉指令是否正確等。
  • 符號引用驗證:這個動作在后面的解析過程中發生,主要是為了確保解析動作能正確執行。
    準備
    準備階段是為類的靜態變量分配內存并將其初始化為默認值,這些內存都將在方法區中進行分配。準備階段不分配類中的實例變量的內存,實例變量將會在對象實例化時隨著對象一起分配在Java堆中。
    public static int value=123;//在準備階段value初始值為0 。在初始化階段才會變為123 。
  • 解析
    該階段主要完成符號引用到直接引用的轉換動作。解析動作并不一定在初始化動作完成之前,也有可能在初始化之后。
    初始化
    初始化時類加載的最后一步,前面的類加載過程,除了在加載階段用戶應用程序可以通過自定義類加載器參與之外,其余動作完全由虛擬機主導和控制。到了初始化階段,才真正開始執行類中定義的Java程序代碼。

    41.簡述java類加載機制?

    虛擬機把描述類的數據從Class文件加載到內存,并對數據進行校驗,解析和初始化,最終形成可以被虛擬機直接使用的java類型。

    42.類加載器雙親委派模型機制?

    當一個類收到了類加載請求時,不會自己先去加載這個類,而是將其委派給父類,由父類去加載,如果此時父類不能加載,反饋給子類,由子類去完成類的加載。

    43.什么是類加載器,類加載器有哪些?

    實現通過類的全限定名獲取該類的二進制字節流的代碼塊叫做類加載器。
    主要有以下四種類加載器:

  • 啟動類加載器(Bootstrap ClassLoader)用來加載java核心類庫,無法被java程序直接引用。
  • 擴展類加載器(extensions class loader):它用來加載 Java 的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄里面查找并加載 Java類。
  • 系統類加載器(system class loader):它根據Java應用的類路徑(CLASSPATH)來加載Java類。一般來說,Java應用的類都是由它來完成加載的。可以通過 ClassLoader.getSystemClassLoader()來獲取它。
  • 用戶自定義類加載器,通過繼承 java.lang.ClassLoader類的方式實現。
  • 44.簡述java內存分配與回收策率以及Minor GC和Major GC

    1.對象優先在堆的Eden區分配。
    2.大對象直接進入老年代.
    3.長期存活的對象將直接進入老年代.
    當Eden區沒有足夠的空間進行分配時,虛擬機會執行一次Minor GC.Minor Gc通常發生在新生代的Eden區,在這個區的對象生存期短,往往發生Gc的頻率較高,回收速度比較快;Full Gc/Major GC 發生在老年代,一般情況下,觸發老年代GC的時候不會觸發Minor GC,但是通過配置,可以在Full GC之前進行一次Minor GC這樣可以加快老年代的回收速度。

    2. JVM內存分配


    3. Java 8的內存分代改進

    從永久代到元空間,在小范圍自動擴展永生代避免溢出

    4. JVM垃圾回收機制,何時觸發MinorGC等操作

    分代垃圾回收機制:不同的對象生命周期不同。把不同生命周期的對象放在不同代上,不同代上采用最合適它的垃圾回收方式進行回收。
    JVM中共劃分為三個代:年輕代、年老代和持久代,
    年輕代:存放所有新生成的對象;
    年老代:在年輕代中經歷了N次垃圾回收仍然存活的對象,將被放到年老代中,故都是一些生命周期較長的對象;
    持久代:用于存放靜態文件,如Java類、方法等。
    新生代的垃圾收集器命名為“minor gc”,老生代的GC命名為”Full Gc 或者Major GC”.其中用System.gc()強制執行的是Full Gc.

    判斷對象是否需要回收的方法有兩種:
    1.引用計數
    當某對象的引用數為0時,便可以進行垃圾收集。
    2.對象引用遍歷
    果某對象不能從這些根對象的一個(至少一個)到達,則將它作為垃圾收集。在對象遍歷階段,gc必須記住哪些對象可以到達,以便刪除不可到達的對象,這稱為標記(marking)對象。

    觸發GC(Garbage Collector)的條件:
    1)GC在優先級最低的線程中運行,一般在應用程序空閑即沒有應用線程在運行時被調用。
    2)Java堆內存不足時,GC會被調用。

    5. jvm中一次完整的GC流程(從ygc到fgc)是怎樣的,重點講講對象如何晉升到老年代等

    答:對象優先在新生代區中分配,若沒有足夠空間,Minor GC;
    大對象(需要大量連續內存空間)直接進入老年態;長期存活的對象進入老年態。如果對象在新生代出生并經過第一次MGC后仍然存活,年齡+1,若年齡超過一定限制(15),則被晉升到老年態。

    6. 你知道哪幾種垃圾收集器,各自的優缺點,重點講下cms,g1

    7. Eden和Survivor的比例分配等

    默認比例8:1。
    大部分對象都是朝生夕死。
    復制算法的基本思想就是將內存分為兩塊,每次只用其中一塊,當這一塊內存用完,就將還活著的對象復制到另外一塊上面。復制算法不會產生內存碎片。

    8. 深入分析了Classloader,雙親委派機制

    ClassLoader:類加載器(class loader)用來加載 Java 類到 Java 虛擬機中。Java 源程序(.java 文件)在經過 Java 編譯器編譯之后就被轉換成 Java 字節代碼(.class 文件)。類加載器負責讀取 Java 字節代碼,并轉換成 java.lang.Class 類的一個實例。
    雙親委派機制:某個特定的類加載器在接到加載類的請求時,首先將加載任務委托給父類加載器,依次遞歸,如果父類加載器可以完成類加載任務,就成功返回;只有父類加載器無法完成此加載任務時,才自己去加載。

    9. JVM的編譯優化

    10. 對Java內存模型的理解,以及其在并發中的應用

    Java內存模型的主要目標: 定義程序中各個變量的訪問規則。
    Java線程之間的通信由Java內存模型(本文簡稱為JMM)控制。
    所有變量的存儲都在主內存,每條線程還都有自己的工作內存,線程的工作內存中保存了被該線程使用到的變量的主內存副本拷貝,線程對變量的所有操作必須在工作內存完成,而不能直接讀取主內存中的變量。不同的線程直接無法訪問對方工作內存中的變量,線程間變量的傳遞均需要通過主內存來完成。

    線程間通信:

  • 首先,線程A把本地內存A中更新過的共享變量刷新到主內存中去。
  • 然后,線程B到主內存中去讀取線程A之前已更新過的共享變量。
  • 11. 指令重排序,內存柵欄等

    指令重排序:編譯器或運行時環境為了優化程序性能而采取的對指令進行重新排序執行的一種手段。在單線程程序中,對存在控制依賴的操作重排序,不會改變執行結果;但在多線程程序中,對存在控制依賴的操作重排序,可能會改變程序的執行結果。

    12. OOM錯誤,stackoverflow錯誤,permgen space錯誤

    13. JVM常用參數

    JVM主要參數:堆設置、回收器選擇(串行、并行、并發收集器)

    14. tomcat結構,類加載器流程


    目錄結構:
    ? /bin:存放windows或Linux平臺上啟動和關閉Tomcat的腳本文件
    ? /conf:存放Tomcat服務器的各種全局配置文件,其中最重要的是server.xml和web.xml
    ? /doc:存放Tomcat文檔
    ? /server:包含三個子目錄:classes、lib和webapps
    ? /server/lib:存放Tomcat服務器所需的各種JAR文件
    ? /server/webapps:存放Tomcat自帶的兩個WEB應用admin應用和 manager應用
    ? /common/lib:存放Tomcat服務器以及所有web應用都可以訪問的jar文件
    ? /shared/lib:存放所有web應用都可以訪問的jar文件(但是不能被Tomcat服務器訪問)
    ? /logs:存放Tomcat執行時的日志文件
    ? /src:存放Tomcat的源代碼
    ? /webapps:Tomcat的主要Web發布目錄,默認情況下把Web應用文件放于此目錄
    ? /work:存放JSP編譯后產生的class文件

    類加載器模式,雙親委派模式:

    15. volatile的語義,它修飾的變量一定線程安全嗎

    一個變量被定義為volatile之后,具備兩重語義:①保證此變量對所有線程的可見性,即當一條線程修改了這個值,新值對于其他所有線程來說是立即得知的,普通變量需要通過主內存傳遞。②禁止指令重排序優化。
    Volatile修飾的變量不一定是線程安全的,eg非原子操作a++等

    16. g1和cms區別,吞吐量優先和響應優先的垃圾收集器選擇

    CMS收集器:一款以獲取最短回收停頓時間為目標的收集器,是基于“標記-清除”算法實現的,分為4個步驟:初始標記、并發標記、重新標記、并發清除。
    G1收集器:面向服務端應用的垃圾收集器,過程:初始標記;并發標記;最終標記;篩選回收。整體上看是“標記-整理”,局部看是“復制”,不會產生內存碎片。
    吞吐量優先的并行收集器:以到達一定的吞吐量為目標,適用于科學技術和后臺處理等。
    響應時間優先的并發收集器:保證系統的響應時間,減少垃圾收集時的停頓時間。適用于應用服務器、電信領域等。

    17. 說一說你對環境變量classpath的理解?如果一個類不在classpath下,為什么會拋出ClassNotFoundException異常,如果在不改變這個類路徑的前期下,怎樣才能正確加載這個類?

    classpath是javac編譯器的一個環境變量。它的作用與import、package關鍵字有關。package的所在位置,就是設置CLASSPATH當編譯器面對import packag這個語句時,它先會查找CLASSPATH所指定的目錄,并檢視子目錄java/util是否存在,然后找出名稱吻合的已編譯文件(.class文件)。如果沒有找到就會報錯!
    動態加載包

    18. 說一下強引用、軟引用、弱引用、虛引用以及他們之間和gc的關系

    強引用:new出的對象之類的引用,只要強引用還在,永遠不會回收
    軟引用:引用但非必須的對象,內存溢出異常之前,回收
    弱引用:非必須的對象,對象能生存到下一次垃圾收集發生之前。
    虛引用:對生存時間無影響,在垃圾回收時得到通知。

    總結

    以上是生活随笔為你收集整理的36.JVM内存分哪几个区,每个区的作用是什么、如和判断一个对象是否存活、java垃圾回收机制、垃圾收集的方法有哪些、java类加载过程、类加载机制、双亲委派、Minor GC和Major GC的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。