天天看點

Java核心知識點整理(一)————JVM(上)Java核心知識點整理(一)————JVM(上)前言一、JVM工作原理二 、線程三、JVM記憶體區域GC

Java核心知識點整理(一)————JVM(上)

Java核心知識點整理–第一篇JVM了解

文章目錄

  • Java核心知識點整理(一)————JVM(上)
  • 前言
  • 一、JVM工作原理
  • 二 、線程
  • 三、JVM記憶體區域
    • 線程私有
      • 1、程式計數器
      • 2、虛拟機棧
      • 3、本地方法區
    • 線程共享
      • 1、堆
      • 2、方法區/永久代
    • 直接記憶體
  • GC
    • 新生代
      • eden區
      • ServivorFrom
      • ServivorTo
      • 整體流程
    • 老年代
    • 永久代

前言

JVM 是可運作 Java 代碼的假想計算機 ,包括一套位元組碼指令集、一組寄存器、一個棧、

一個垃圾回收,堆 和 一個存儲方法域。JVM 是運作在作業系統之上的,它與硬體沒有直接

的互動。

一、JVM工作原理

Java 源檔案,通過編譯器,能夠生産相應的.Class 檔案,也就是位元組碼檔案,

而位元組碼檔案又通過 Java 虛拟機中的解釋器,編譯成特定機器上的機器碼 。

也就是如下:

① Java 源檔案—->編譯器—->位元組碼檔案

② 位元組碼檔案—->JVM—->機器碼

每一種平台的解釋器是不同的,但是實作的虛拟機是相同的,這也就是 Java 為什麼能夠跨平台的原因了 ,當一個程式從開始運作,這時虛拟機就開始執行個體化了,多個程式啟動就會存在多個虛拟機執行個體。程式退出或者關閉,則虛拟機執行個體消亡,多個虛拟機執行個體之間資料不能共享。

Java核心知識點整理(一)————JVM(上)Java核心知識點整理(一)————JVM(上)前言一、JVM工作原理二 、線程三、JVM記憶體區域GC

二 、線程

這裡所說的線程指程式執行過程中的一個線程實體。JVM 允許一個應用并發執行多個線程。

Hotspot JVM 中的 Java 線程與原生作業系統線程有直接的映射關系。當線程本地存儲、緩沖區配置設定、同步對象、棧、程式計數器等準備好以後,就會建立一個作業系統原生線程。Java 線程結,原生線程随之被回收。作業系統負責排程所有線程,并把它們配置設定到任何可用的 CPU 上。當原生線程初始化完畢,就會調用 Java 線程的 run() 方法。當線程結束時,會釋放原生線程和 Java 線程的所有資源。

Java核心知識點整理(一)————JVM(上)Java核心知識點整理(一)————JVM(上)前言一、JVM工作原理二 、線程三、JVM記憶體區域GC

三、JVM記憶體區域

Java核心知識點整理(一)————JVM(上)Java核心知識點整理(一)————JVM(上)前言一、JVM工作原理二 、線程三、JVM記憶體區域GC

JVM記憶體分為三大子產品 線程私有、線程共享、直接記憶體。

線程私有

資料區域生命周期與線程相同,根據線程的啟動和結束來建立和銷毀。

每個線程都與作業系統的本地線程直接映射, 是以這部分記憶體區域的存/否跟随本地線程的

生/死對應)。同時線程私有區域包含程式計數器、虛拟機棧、本地方法區

1、程式計數器

一塊較小的記憶體空間,是目前線程所執行的位元組碼的信号訓示器。每條線程都要有獨立的程式計數器,是以這類記憶體也成為線程私有記憶體。

正在執行 java 方法的話,計數器記錄的是虛拟機位元組碼指令的位址(目前指令的位址)。如

果還是 Native 方法,則為空。

這個記憶體區域是唯一一個在虛拟機中沒有規定任何 OutOfMemoryError 情況的區域。

2、虛拟機棧

用來描述執行java方法的記憶體模型,每個方法執行的時候會建立一個棧幀用于存儲局部變量表、操作數棧、動态連結、方法出口等資訊。每個方法調用執行完成的過程,就對應着一個棧幀在虛拟機裡入棧到出棧的過程。

。棧幀随着方法調用而建立,随着方法結束而銷毀。無論方法是否正常完成都算作方法結束。

3、本地方法區

本地方法區和JAVA Stack作用相似,差別是虛拟機棧為執行java方法服務,而本地方法則為native方法服務

什麼是native方法?

一個Native Method就是一個Java調用非java代碼的接口。一個Native Method是這樣一個 java的方法:該方法的實作由非java語言實作,比如C。這個特征并非java所特有,很多其它的程式設計語言都有這一機制,比如在C++中,你可以用extern"C"告知C++編譯器去調用一個C的函數。 “A native method is a Java method whose implementation is provided by non-java code.”

線程共享

線程共享區域随虛拟機的啟動/關閉而建立/銷毀。它具有JAVA 堆、方法區這兩個部分

1、堆

堆是線程共享的一塊記憶體區域,建立的對象和數組都儲存在 Java 堆記憶體中,也是垃圾收集器進行垃圾收集的最重要的記憶體區域。由于現代 VM 采用分代收集算法, 是以 Java 堆從 GC 的角度還可以細分為: 新生代(Eden 區、From Survivor 區和 To Survivor 區)和老年代。關于GC我們後面再去了解。

2、方法區/永久代

永久代(Permanent Generation), 用于存儲被 JVM 加載的類資訊、常量、靜态變量、即時編譯器編譯後的代碼等資料.

HotSpot VM把GC分代收集擴充至方法區, 即使用Java堆的永久代來實作方法區, 這樣 HotSpot 的垃圾收集器就可以像管理 Java 堆一樣管理這部分記憶體,而不必為方法區開發專門的記憶體管理器(永久帶的記憶體回收的主要目标是針對常量池的回收和類型的解除安裝, 是以收益一般很小)。

運作時常量池(Runtime Constant Pool)是方法區的一部分。Class 檔案中除了有類的版本、字段、方法、接口等描述等資訊外,還有一項資訊是常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符号引用,這部分内容将在類加載後存放到方法區的運作時常量池中。 Java 虛拟機對 Class 檔案的每一部分(自然也包括常量池)的格式都有嚴格的規定,每一個位元組用于存儲哪種資料都必須符合規範上的要求,這樣才會被虛拟機認可、裝載和執行。

直接記憶體

直接記憶體并不是 JVM 運作時資料區的一部分, 但也會被頻繁的使用: 在 JDK 1.4 引入的 NIO 提

供了基于 Channel 與 Buffer 的 IO 方式, 它可以使用 Native 函數庫直接配置設定堆外記憶體, 然後使用

DirectByteBuffer 對象作為這塊記憶體的引用進行操作, 這樣就避免了在 Java堆和 Native 堆中來回複制資料, 是以在一些場景中可以顯著提高性能。

GC

Java 堆從 GC 的角度還可以細分為: 新生代(Eden 區、From Survivor 區和 To Survivor 區)和老年

代。

新生代

Java 新對象的出生地(如果新建立的對象占用記憶體很大,則直接配置設定到老年代)。當 Eden 區記憶體不夠的時候就會觸發 MinorGC,對新生代區進行一次垃圾回收。

新生代又分為 Eden 區、ServivorFrom、ServivorTo 三個區。

空間大小設成 8 : 1 : 1

eden區

Java 新對象的出生地(如果新建立的對象占用記憶體很大,則直接配置設定到老年代)。當 Eden 區記憶體不夠的時候就會觸發 MinorGC,對新生代區進行一次垃圾回收。

ServivorFrom

上一次 GC 的幸存者,作為這一次 GC 的被掃描者。

ServivorTo

保留了一次 MinorGC 過程中的幸存者。

整體流程

Eden是一塊連續的記憶體,是以配置設定記憶體的速度很快。

首先,Eden滿時,進行一次minor gc ,将存活 的對象複制到 To Survivor(以下簡稱To),清除Eden消亡的對象。當Eden再次滿時,進行minor gc,To中能夠晉升的移動到老年代,存活的對象複制到From。

老年代

主要存放應用程式中生命周期長的記憶體對象。

老年代的對象比較穩定,是以 MajorGC 不會頻繁執行。在進行 MajorGC 前一般都先進行了一次 MinorGC,使得有新生代的對象晉身入老年代,導緻空間不夠用時才觸發。當無法找到足夠大的連續空間配置設定給新建立的較大對象時也會提前觸發一次 MajorGC 進行垃圾回收騰出空間。 MajorGC 采用标記清除算法:首先掃描一次所有老年代,标記出存活的對象,然後回收沒有标記的對象。ajorGC 的耗時比較長,因為要掃描再回收。MajorGC 會産生記憶體碎片,為了減少記憶體損耗,我們一般需要進行合并或者标記出來友善下次直接配置設定。當老年代也滿了裝不下的時候,就會抛出 OOM(Out of Memory)異常。

永久代

指記憶體的永久儲存區域,主要存放 Class 和 Meta(中繼資料)的資訊,Class 在被加載的時候被放入永久區域,它和和存放執行個體的區域不同,GC 不會在主程式運作期對永久區域進行清理。是以這也導緻了永久代的區域會随着加載的 Class 的增多而脹滿,最終抛出 OOM 異常。