<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                **1. 說一下 JVM 的主要組成部分?及其作用?** - 類加載器(ClassLoader) - 運行時數據區(Runtime Data Area) - 執行引擎(Execution Engine) - 本地庫接口(Native Interface) 組件的作用:?首先通過類加載器(ClassLoader)會把 Java 代碼轉換成字節碼,運行時數據區(Runtime Data Area)再把字節碼加載到內存中,而字節碼文件只是 JVM 的一套指令集規范,并不能直接交給底層操作系統去執行,因此需要特定的命令解析器執行引擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程中需要調用其他語言的本地庫接口(Native Interface)來實現整個程序的功能。 ***** **2. 說一下 JVM 運行時數據區?** 不同虛擬機的運行時數據區可能略微有所不同,但都會遵從 Java 虛擬機規范, Java 虛擬機規范規定的區域分為以下 5 個部分: - 程序計數器(Program Counter Register):當前線程所執行的字節碼的行號指示器,字節碼解析器的工作是通過改變這個計數器的值,來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能,都需要依賴這個計數器來完成; - Java 虛擬機棧(Java Virtual Machine Stacks):用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息; -本地方法棧(Native Method Stack):與虛擬機棧的作用是一樣的,只不過虛擬機棧是服務 Java 方法的,而本地方法棧是為虛擬機調用 Native 方法服務的; - Java 堆(Java Heap):Java 虛擬機中內存最大的一塊,是被所有線程共享的,幾乎所有的對象實例都在這里分配內存; ***** - 方法區(Methed Area):用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯后的代碼等數據。 **3. 說一下堆棧的區別?** - 功能方面:堆是用來存放對象的,棧是用來執行程序的。 - 共享性:堆是線程共享的,棧是線程私有的。 - 空間大小:堆大小遠遠大于棧。 **4. 什么是雙親委派模型?** 在介紹雙親委派模型之前先說下類加載器。對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立在 JVM 中的唯一性,每一個類加載器,都有一個獨立的類名稱空間。類加載器就是根據指定全限定名稱將 class 文件加載到 JVM 內存,然后再轉化為 class 對象。 類加載器分類: - 啟動類加載器(Bootstrap ClassLoader),是虛擬機自身的一部分,用來加載Java_HOME/lib/目錄中的,或者被 -Xbootclasspath 參數所指定的路徑中并且被虛擬機識別的類庫; - 擴展類加載器(Extension ClassLoader):負責加載<Java_HOME>\lib\ext目錄或Java. ext. dirs系統變量指定的路徑中的所有類庫; - 應用程序類加載器(Application ClassLoader)。負責加載用戶類路徑(classpath)上的指定類庫,我們可以直接使用這個類加載器。一般情況,如果我們沒有自定義類加載器默認就是用這個加載器。 雙親委派模型:如果一個類加載器收到了類加載的請求,它首先不會自己去加載這個類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣所有的加載請求都會被傳送到頂層的啟動類加載器中,只有當父加載無法完成加載請求(它的搜索范圍中沒找到所需的類)時,子加載器才會嘗試去加載類。 **5. 說一下類裝載的執行過程?** 類裝載分為以下 5 個步驟: - 加載:根據查找路徑找到相應的 class 文件然后導入; - 檢查:檢查加載的 class 文件的正確性; - 準備:給類中的靜態變量分配內存空間; - 解析:虛擬機將常量池中的符號引用替換成直接引用的過程。符號引用就理解為一個標示,而在直接引用直接指向內存中的地址; - 初始化:對靜態變量和靜態代碼塊執行初始化工作。 ***** **6. 怎么判斷對象是否可以被回收?** - 引用計數器:為每個對象創建一個引用計數,有對象引用時計數器 +1,引用被釋放時計數 -1,當計數器為 0 時就可以被回收。它有一個缺點不能解決循環引用的問題; - 可達性分析:從 GC Roots 開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連時,則證明此對象是可以被回收的。 ***** **7. Java 中都有哪些引用類型?** - 強引用:發生 gc 的時候不會被回收。 - 軟引用:有用但不是必須的對象,在發生內存溢出之前會被回收。 - 弱引用:有用但不是必須的對象,在下一次GC時會被回收。 - 虛引用(幽靈引用/幻影引用):無法通過虛引用獲得對象,用 PhantomReference 實現虛引用,虛引用的用途是在 gc 時返回一個通知。 **8. 說一下 JVM 有哪些垃圾回收算法?** - 標記-清除算法:標記無用對象,然后進行清除回收。缺點:效率不高,無法清除垃圾碎片。 - 標記-整理算法:標記無用對象,讓所有存活的對象都向一端移動,然后直接清除掉端邊界以外的內存。 - 復制算法:按照容量劃分二個大小相等的內存區域,當一塊用完的時候將活著的對象復制到另一塊上,然后再把已使用的內存空間一次清理掉。缺點:內存使用率不高,只有原來的一半。 - 分代算法:根據對象存活周期的不同將內存劃分為幾塊,一般是新生代和老年代,新生代基本采用復制算法,老年代采用標記整理算法。 ***** **9. 說一下 JVM 有哪些垃圾回收器?** - Serial:最早的單線程串行垃圾回收器。 - Serial Old:Serial 垃圾回收器的老年版本,同樣也是單線程的,可以作為 CMS 垃圾回收器的備選預案。 - ParNew:是 Serial 的多線程版本。 - Parallel 和 ParNew 收集器類似是多線程的,但 Parallel 是吞吐量優先的收集器,可以犧牲等待時間換取系統的吞吐量。 - Parallel Old 是 Parallel 老生代版本,Parallel 使用的是復制的內存回收算法,Parallel Old 使用的是標記-整理的內存回收算法。 - CMS:一種以獲得最短停頓時間為目標的收集器,非常適用 B/S 系統。 - G1:一種兼顧吞吐量和停頓時間的 GC 實現,是 JDK 9 以后的默認 GC 選項。 ***** **10. 詳細介紹一下 CMS 垃圾回收器?** CMS 是英文 Concurrent Mark-Sweep 的簡稱,是以犧牲吞吐量為代價來獲得最短回收停頓時間的垃圾回收器。對于要求服務器響應速度的應用上,這種垃圾回收器非常適合。在啟動 JVM 的參數加上“-XX:+UseConcMarkSweepGC”來指定使用 CMS 垃圾回收器。 CMS 使用的是標記-清除的算法實現的,所以在 gc 的時候回產生大量的內存碎片,當剩余內存不能滿足程序運行要求時,系統將會出現 Concurrent Mode Failure,臨時 CMS 會采用 Serial Old 回收器進行垃圾清除,此時的性能將會被降低。 ***** **11. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么區別?** 新生代垃圾回收器一般采用的是復制算法,復制算法的優點是效率高,缺點是內存利用率低;老年代回收器一般采用的是標記-整理的算法進行垃圾回收。 ***** **12. 簡述分代垃圾回收器是怎么工作的?** 分代回收器有兩個分區:老生代和新生代,新生代默認的空間占比總空間的 1/3,老生代的默認占比是 2/3。 新生代使用的是復制算法,新生代里有 3 個分區:Eden、To Survivor、From Survivor,它們的默認占比是 8:1:1,它的執行流程如下: - 把 Eden + From Survivor 存活的對象放入 To Survivor 區; - 清空 Eden 和 From Survivor 分區; - From Survivor 和 To Survivor 分區交換,From Survivor 變 To Survivor,To Survivor 變 From Survivor。 每次在 From Survivor 到 To Survivor 移動時都存活的對象,年齡就 +1,當年齡到達 15(默認配置是 15)時,升級為老生代。大對象也會直接進入老生代。 老生代當空間占用到達某個值之后就會觸發全局垃圾收回,一般使用標記整理的執行算法。以上這些循環往復就構成了整個分代垃圾回收的整體執行流程。 ***** **13. 說一下 JVM 調優的工具?** JDK 自帶了很多監控工具,都位于 JDK 的 bin 目錄下,其中最常用的是 jconsole 和 jvisualvm 這兩款視圖監控工具。 -jconsole:用于對 JVM 中的內存、線程和類等進行監控; -jvisualvm:JDK 自帶的全能分析工具,可以分析:內存快照、線程快照、程序死鎖、監控內存的變化、gc 變化等。 ***** **14. 常用的 JVM 調優的參數都有哪些?** - Xms2g:初始化堆大小為 2g; - Xmx2g:堆最大內存為 2g; - XX:NewRatio=4:設置年輕的和老年代的內存比例為 1:4; - XX:SurvivorRatio=8:設置新生代 Eden 和 Survivor 比例為 8:2; - XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器組合; - XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合; - XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器組合; - XX:+PrintGC:開啟打印 gc 信息; - XX:+PrintGCDetails:打印 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>

                              哎呀哎呀视频在线观看