劍指Offer——JVM 基礎知識點儲備

      網友投稿 607 2025-04-04

      @TOC


      一、前言

      應聘后端開發崗位面試過程中,有關JVM的問題必不可少,此篇博文主要梳理有關JVM工作原理、收集器有關內容。

      二、java 內存與內存溢出

      2.1 JVM 分區及作用

      程序計數器(線程私有)

      當前線程執行字節碼的信號指示器。(每個線程都會在程序計數器中存儲其指令,從而實現線程切換后恢復到正確的執行位置)

      虛擬機棧(棧,線程私有)

      劍指Offer——JVM 基礎知識點儲備

      每個方法執行(開始到結束就是這個方法的生命周期)都會創建一個棧幀,棧幀存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。

      (棧內存)為虛擬機執行java方法服務:方法被調用時創建棧幀–>局部變量表–>局部變量–>對象引用

      如果線程請求的棧深度超出了虛擬機所允許的深度,就會出現StackOverFlowError. -Xss規定了棧的最大空間;

      虛擬機棧可以動態擴展,如果擴展到無法申請到足夠的內存,會出現OOM(OutOfMemoryError)

      而我們最常用的就是局部變量表,局部變量表包括如下內容:

      基本數據類型: boolean byte char short int float long double

      注意基本類型的包裝類型:Boolean、Byte、Character、Short、Integer、Float、Long、Double

      對象引用類型:類、接口、數組 (不是對象本身,可能是一個指向對象起始地址的引用指針)

      問題:包裝類型是放在棧中么:String Interget(看包裝類型是怎么用的:若直接定義則內容在常量池中,若new一個對象則在堆中。)

      本地方法棧 。與虛擬機實現的功能非常相似,不同之處在于虛擬機執行java方法(字節碼)服務,而本地方法棧執行Native 方法服務(非java方法寫的)。

      java 堆。(線程共享) 虛擬機啟動時創建,此內存區域的唯一目的就是存放對象實例,對象在失去引用,就會被java虛擬機回收。

      被所有線程共享,在java虛擬機啟動時創建,幾乎所有的對象實例都存放到堆中;

      GC管理的主要區域;

      物理上不連續,邏輯上連續,并可以動態擴展,無法擴展時拋出OutOfMemoryError;

      方法區(線程共享)(虛擬機把方法區叫做永久代)。

      用于存儲已被虛擬機加載的類信息、常量、靜態變量、即編譯器編譯后的代碼等數據。

      注意??:特別注意靜態變量static修飾的變量在方法區。

      直接內存(了解即可)

      不是虛擬機運行時數據區的一部分。是native函數直接分配的堆外內存,這樣避免了java堆和native堆來回復制數據。

      三、垃圾收集器與內存分配策略

      3.1 jvm垃圾處理方法(標記清除、復制、標記整理)

      標記—清除算法

      標記階段:先通過根節點,標記所有從根節點開始的對象,未被標記的視為垃圾對象;

      清除階段:清除所有未被標記的對象。

      復制算法

      將原有的內存空間分成兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的內存中存活對象復制到未使用的內存塊中,然后清除正在使用的內存塊中所有對象。

      標記—整理算法

      若對象存活率比較高,就要進行多次復制,效率比較低。

      標記階段:先通過根節點,標記所有從根節點開始的可達對象,未被標記的視為垃圾對象。

      整理階段:將所有的存活對象壓縮到內存的一端(或向一端移動),之后清理邊界所有的空間。

      分代收集算法

      只是根據對象存活周期的不同將內存劃分為幾塊。一般把java堆分為新生代和老年代。

      新生代大量對象死亡,只有少數對象存活,采用復制算法;

      老年代對象存活率高,沒有額外空間對它進行分配,故采用標記-清除或標記-整理算法。

      三種算法的比較:

      效率:復制算法 > 標記-整理算法 > 標記-清除算法(此處的效率只是簡單的對比時間復雜度)

      內存整理度:復制算法 = 標記-整理算法 》標記-清除算法

      內存利用率:標記-整理算法 = 標記-清除算法 》復制算法

      3.2 JVM如何GC?新生代,老年代,持久代,都存儲哪些東西,以及各個區的作用?

      大多數新生的對象在Eden區分配,當Eden區沒有足夠空間進行分配時,虛擬機就會進行一次Minor GC。(Survivor是兩個)

      1. 新生代

      在方法中new一個對象,方法調用完畢后,對象就會被回收,這就是一個典型的新生代對象。(新生對象在eden區經歷過一次minorGC并且被Survivor容納的話,對象年齡為1,每一次熬過MinorGc 年齡就會加1,直到15,就會晉升到老年。)

      注意動態對象的判定:Survivor空間中相同年齡的對象大小總和大于Survivo空間的一半,大于或等于該年齡的對象就可以直接進入老年代。

      老年代

      在新生代中經歷了N次垃圾回收后仍然存活的對象,就會被放到老年代中,而且大對象(占用大量連續內存空間的java對象如很長的字符串及數組)直接進入老年代。

      當survivor空間不夠用時,需要依賴老年代進行分配擔保。

      3.3 GC 引用可達性分析算法中 GCRoots 對象

      java虛擬機棧中的對象(引用對象);

      方法區中的靜態成員;

      方法區中的常量引用對象;

      本地方法區中的JNI(Native方法)引用對象 ;

      3.4 MinorGC、FullGC時機

      1. MinorGC(新生代GC)

      當Eden區沒有足夠空間進行分配時,虛擬機就會進行一次Minor GC。

      新生代中的垃圾收集動作,采用的是復制算法;

      對于較大的對象(很長的字符串、數據、集合),在Minor GC的時候可以直接進入老年代。

      2. FullGC(老年代GC)

      Full GC 是發生在老年代的垃圾收集動作,采用的是標記-清除/整理算法;

      由于老年代的對象幾乎都是在survivor區熬過來的,不會那么容易死掉,因此Full GC發生的次數不會像MInor GC那么頻繁,Full GC清理時間是Minor GC的10倍。

      3.5 各垃圾回收器工作原理

      是一個單線程收集器,它“單線程”的意義并不僅僅說明它只會使用一個cpu或一條線程去完成垃圾回收工作。而是在收集垃圾時,暫停其他的工作線程。

      新生代采用復制算法,stop-the-world(消除或者減少工作線程因內存回收而導致停頓)。

      老年代采用標記–整理算法。

      簡單高效,client模式下默認的新生代收集器。

      ParNew收集器是Serial收集器的多線程版本;

      新生代采用復制算法,stop-the-world;

      老年代采用標記–整理算法;

      它是運行在server模式下首選新生代收集器;

      除了serial收集器之外,只能它能和cms收集器配合工作。

      類似ParNew,但是更加關注吞吐量。目標是:達到一個可控制吞吐量的收集器;

      停頓時間和吞吐量不可能同時調優。我們一方面希望停頓時間少,另一方面希望吞吐量高,其實這是矛盾的。

      因為:在GC的時候,垃圾回收的工作量是不變的,如果停頓時間減少,那頻率就會提高;既然頻率提高了,說明就會頻繁的進行GC,那吞吐量就會減少,性能就會降低。

      是當今收集器發展的最前沿成果之一,對垃圾回收進行劃分優先級的操作,這種有優先級的區域回收方法保證了它的高效率;

      最大的優點是結合了空間整合,不會產生大量的碎片,也降低了進行GC的頻率;

      讓使用者明確指定停頓的時間。

      一種以獲得最短回收停頓時間為目標的收集器,適用于互聯網網站或者B/S系統的服務器上;

      初始化標記(stop-the-world):根可以直接關聯到的對象;

      并發標記(和用戶線程一起):主要標記過程,標記全部對象;

      重新標記(stop-the-world):由于并發標記時,用戶線程依然運行,因此在正式清理前,再做修正;

      并發清除(和用戶線程一起):基于標記結果,直接清理對象。

      注意:CMS有三個致命的問題:

      cpu資源占用;

      浮動的垃圾無法清除;

      內存碎片;

      3.6 java 引用類型

      Java有四種引用類型:

      強引用:通過new產生的對象都是強引用。

      軟引用:一些還有用但不是必須的對象可以使用軟引用。比如創建一個軟引用數組,這個數組存放了100多個學生對象的信息。內存比較空閑的時候這些對象和強引用沒有區別,但內存緊張的時候就會被GC回收。(這就是GC的判定條件)

      應用軟引用的好處:java在內存不足時,程序不會崩潰;

      弱引用:描述非必須對象的(比軟引用更弱),當GC工作時,無論內存是否緊張都會回收掉;當某個對象是偶爾使用,并且在使用時隨時能獲取,又不想影響垃圾的回收,可以考慮應用這個。

      虛引用:無法通過虛引用來獲取對一個對象的真實引用。唯一的用處:能在對象被GC時收到系統通知,JAVA中用PhantomReference來實現虛引用。

      Java JVM

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:PPT沒有導出視頻這個選擇了怎么辦(為什么ppt導出的視頻無法播放)
      下一篇:excel表格數字設置遞減的教程
      相關文章
      亚洲AV无码专区在线亚| 亚洲中字慕日产2021| 久久亚洲最大成人网4438| 亚洲JIZZJIZZ中国少妇中文| 亚洲精品无码午夜福利中文字幕 | 亚洲人成电影网站色www| 亚洲成A∨人片天堂网无码| 久久亚洲中文无码咪咪爱| 久久综合图区亚洲综合图区| 日本亚洲欧美色视频在线播放 | 亚洲性天天干天天摸| 日产国产精品亚洲系列| 亚洲中文字幕久在线| 亚洲一区二区三区在线网站| 久久精品国产亚洲av麻豆图片| 亚洲综合久久一本伊伊区| 亚洲精品中文字幕无乱码麻豆| 亚洲av成人一区二区三区| 伊人久久亚洲综合影院首页| 亚洲高清日韩精品第一区| 国产A在亚洲线播放| 亚洲一级特黄大片无码毛片| 亚洲一本到无码av中文字幕| 亚洲女子高潮不断爆白浆| 亚洲成av人片在线天堂无| 亚洲女人初试黑人巨高清| 亚洲AV无码成人网站久久精品大 | 亚洲日本乱码一区二区在线二产线| 久久亚洲sm情趣捆绑调教| 亚洲ts人妖网站| 亚洲精品无码成人片久久不卡| WWW亚洲色大成网络.COM| 亚洲福利精品一区二区三区| 亚洲伊人久久综合中文成人网 | 亚洲a级成人片在线观看| 亚洲欧洲无卡二区视頻| 亚洲成年看片在线观看| 亚洲午夜福利在线观看| 亚洲精品乱码久久久久久不卡| 亚洲GV天堂GV无码男同| 亚洲国产精品视频|