Java內存機制詳解|JVM初步

Java內存機制詳解|JVM初步

JVM

JVM執行引擎

  • 解釋器
  • JIT(Just In Time),優先次執行的字節碼會編譯成本地的機器代碼,被緩存在系統中,以後可以隨時調用
  • 自適應的優化器,虛擬機開始的時候解釋字節碼CodeGo.net,但是會監控運行中程序的活動,並記錄下使用最頻繁的代碼段,虛擬機會把這些活動最頻繁的代碼段編譯成本地代碼。還有一種虛擬機是由硬件芯片構成,它用本地方法執行java字節碼

JVM程序執行過程

  1. 加載.class文件
  2. 管理分配內存
  3. 執行垃圾收集

JVM生命週期

  1. 啓動
    啓動一個Java 程序時,一個JVM 實例就產生了,任何一個又有 public static void main(String[] args) 函數的class 文件都可以作爲JVM 實例運行的起點。
  2. 運行
    main()作爲該程序初始線程的起點,任何其他線程均由該線程啓動。JVM 內部有兩種線程:守護線程和非守護線程,main()屬於非守護線程,守護線程通常由JVM 自己使用,java 程序也可以表明自己創建的線程是守護線程。
  3. 消亡
    當程序中的所有非守護線程都終止時,JVM 才退出;若安全管理器允許,程序也可以使用Runtime類或者System.exit()來退出。

JVM的邏輯內存模型

(重點重點[敲黑板],仔細查看外鏈博客[敲黑板])

JVM的邏輯內存模型

深入理解JVM—JVM內存模型

方法區:方法區(Method Area)與Java 堆一樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。雖然Java 虛擬機規範把方法區描述爲堆的一個邏輯部分,但是它卻有一個別名叫做Non-Heap(非堆),目的應該是與Java 堆區分開來。
要注意方法區單獨開闢,不同於堆內存,意在一些類的公共的方法可以共享,堆內對象還有引用指向方法區。

運行時常量池:運行時常量池(Runtime Constant Pool)是方法區的一部分。Class 文件中除了有類的版本、字段、方法、接口等描述等信息外。還有一項信息是常量池(Constant PoolTable),用於存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載後存放到方法區的運行時常量池中。

常量池(ConstantPool):常量池在編譯期間就將一部分數據存放於該區域,包含基本數據類型如int、long等和對象類型String、數組等並以final聲明的常量值。特別注意的是對於運行期位於棧中的String常量的值可以通過 String.intern()方法將該值置入到常量池中。

JVM體系結構

JVM體系結構

內存分配及變量存儲位置(堆、棧、方法區常量池、方法區靜態區)

返回值:會在棧空間中臨時開闢一塊空間臨時存放,在方法執行完成後消失。

JVM原理

JVM原理

堆內存和棧內存

棧內存

當在一段代碼塊定義一個變量時,Java 就在棧中爲這個變量分配內存空間。棧中主要存放一些基本類型的變量(int, short, long, byte, float,double, boolean, char)和對象句柄。
棧有一個很重要的特殊性,就是存在棧中的數據可以共享。

堆內存

堆內存用來存放由new 創建的對象和數組

eg
假設我們同時定義:
int a = 3;
int b = 3;
編譯器先處理int a = 3;首先它會在棧中創建一個變量爲a 的引用,然後查找棧中是否有3 這個值,如果沒找到,就將3 存放進來,然後將a 指向3。接着處理int b = 3;在創建完b 的引用變量後,因爲在棧中已經有3 這個值,便將b 直接指向3。這樣,就出現了a 與b 同時均指向3 的情況。這時,如果再令a=4;那麼編譯器會重新搜索棧中是否有4 值,如果沒有,則將4 存放進來,並令a 指向4;如果已經有了,則直接將a 指向這個地址。因此a 值的改變不會影響到b 的值。要注意這種數據的共享與兩
個對象的引用同時指向一個對象的這種共享是不同的,因爲這種情況a 的修改並不會影響到b,它是由編譯器完成的,它有利於節省空間。而一個對象引用變量修改了這個對象的內部狀態,會影響到另一個對象引用變量。

String 是一個特殊的包裝類數據。可以用:
String str = new String("abc");
String str = "abc";
兩種的形式來創建,第一種是用new()來新建對象的,它會在存放於堆中。每調用一次就會創建一個新的對象。而第二種是先在棧中創建一個對String 類的對象引用變量str,然後查找棧中有沒有存放"abc",如果沒有,則"abc"存放進棧,並令str 指向"abc",如果已經有"abc"則直接令str 指向"abc"

JVM 垃圾回收

GC (Garbage Collection)的基本原理:
將內存中不再被使用的對象進行回收,GC 中用於回收的方法稱爲收集器,由於GC 需要消耗一些資源和時間,Java 在對對象的生命週期特徵進行分析後,按照新生代、舊生代的方式來對對象進行收集,以儘可能的縮短GC 對應用造成的暫停。

java 虛擬機會在6 種情況下創建一個對象

  1. 創建類的新實例
  2. 調用類中聲明的靜態方法
  3. 操作類或接口中聲明的非常量靜態字段
  4. 調用Java API 中特定的反射方法
  5. 初始化一個類的子類
  6. 制定一個類作爲Java 虛擬機啓動時的初始化類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章