面試 1:簡述JVM的內存佈局

1. 我的回答

  • JVM內存佈局分兩塊:線程共享和非線程共享。線程共享區域有堆區、方法區;非線程共享區有程序計數器、方法棧、本地方法區。
  • 堆區:當對象被創建時,就在堆中開闢相應的內存空間,用來存儲對象中的非靜態成員變量,指向方法區的方法描述。這裏是垃圾回收的區域。
  • 方法區:類的class字節碼加載到此區域中,並開闢相應的靜態空間。
  • 程序計數器:記錄棧幀中方法執行的字節碼指令的位置。
  • 方法棧:以棧幀爲單位,每調用一個新的方法,就開闢一個棧幀,棧幀中存放的局部變量表,方法參數,本地方法等諸多信息。
  • 本地方法區:調用到了其他語言的代碼。
    在這裏插入圖片描述

2. 滿分回答

  • 堆區:是線程共享的區域(和java程序的生命週期相同)。java堆中用來存放實例對象以及數組對象。由於現在有了逃逸分析技術,也可以將對象分配在棧中。
    解釋:逃逸分析技術是將對象在棧中分配的一種技術,因爲棧空間相對堆空間較小,所以該對象一般是小對象。
    同時,java堆也是垃圾回收的主要區域,垃圾回收主要採取分代回收的方式,有年輕代,老年代,如下圖。
    在這裏插入圖片描述
    java堆中是可以是物理上不連續的區域,只要邏輯上連續即可。在堆中分配內存的方法有:
    • 碰撞指針:在連續剩餘空間中分配內存。用一個指針指向內存已用區和空閒區的分界點,需要分配新的內存時候,只需要將指針向空閒區移動相應的距離即可。
    • 空閒列表:在不規整的剩餘空間中分配內存。如果剩餘內存是不規整的,就需要用一個列表記錄下哪些內存塊是可用的,當需要分配內存的時候就需要在這個列表中查找,找到一個足夠大的空間進行分配,然後在更新這個列表。
      注:分配的選擇方式取決於採用的垃圾回收算法。指針碰撞的分配方式明顯要優於空閒列表的方式,但是使用哪種方式取決於堆內存是否規整,而堆內存是否規整則由使用的垃圾收集算法決定。如果堆內存是規整的,則採用指針碰撞的方式分配內存,而如果堆是不規整的,就會採用空閒列表的方式。
      標記-清除算法:
      在這裏插入圖片描述
      標記-壓縮算法:
      在這裏插入圖片描述
      對象訪問方式有兩種:句柄和直接訪問
  • 方法區:與堆一樣,是線程的共享區域。用於存儲已經被虛擬機加載的類的信息、常量、靜態變量、編譯後的代碼,運行時常量池。方法區中有一個運行時常量池,class文件中的常量池在類加載後就被放入運行時常量池。運行時常量池相對於class文件中的常量池,具有動態性。可以在運行期間通過intern將常量放入池中,方法區空間不足拋出outOfMemoryError,和堆一樣。
  • 程序計數器:該區域是內存中較小的一塊區域,是當前線程在執行的字節碼的行號指示器。程序計數器是線程私有的,每個線程都有一個程序計數器,線程之間的程序計數器相互獨立,互不干擾。是jvm規範中唯一一個沒有規定任何outOfMemoryError情況的區域
  • 虛擬機棧:是線程私有的,其生命週期與線程相同。虛擬機描述的是java方法執行的內存模型,每個方法執行的時候,都會創建一個棧幀用於存儲局部變量表,操作數棧、動態鏈接、方法出口信息。每個方法從調用結束就會有棧幀在虛擬機棧中入棧和出棧。一個方法的調用鏈可能會很長,於是當調用一個方法時,可能會有很多方法都處於執行狀態,但對於執行引擎來講,至於位於虛擬機棧頂的棧幀纔是有效的,這個棧幀被稱爲當前的。StackOverFlowerror異常。
發佈了106 篇原創文章 · 獲贊 91 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章