1. 程式人生 > >java記憶體模型和記憶體分配

java記憶體模型和記憶體分配

1.什麼是jvm?

(1)jvm是一種用於計算裝置的規範,它是一個虛構出來的機器,是通過在實際的計算機上模擬模擬各種功能實現的。

(2)jvm包含一套位元組碼指令集,一組暫存器,一個棧,一個垃圾回收堆和一個儲存方法域。

(3)JVM遮蔽了與具體作業系統平臺相關的資訊,使Java程式只需生成在Java虛擬機器上執行的目的碼(位元組碼),就可以在多種平臺上不加修改地執行。

JVM在執行位元組碼時,實際上最終還是把位元組碼解釋成具體平臺上的機器指令執行。

2.jdk、jre、jvm是什麼關係?

(1)JRE(Java Runtime Environment),也就是java平臺。所有的java程式都要在JRE環境下才能執行。

(2)JDK(Java Development Kit),是開發者用來編譯、除錯程式用的開發包。JDK也是JAVA程式需要在JRE上執行。

(3)JVM(Java Virtual Machine),是JRE的一部分。它是一個虛構出來的計算機,是通過在實際的計算機上模擬模擬各種計算機功能來實現的。

JVM有自己完善的硬體架構,如處理器、堆疊、暫存器等,還具有相應的指令系統。

Java語言最重要的特點就是跨平臺執行。使用JVM就是為了支援與作業系統無關,實現跨平臺。

3.JVM原理

(1)jvm是java的核心和基礎,在java編譯器和os平臺之間的虛擬處理器,可在上面執行位元組碼程式。

(2)java編譯器只要面向jvm,生成jvm能理解的位元組碼檔案。java原始檔經編譯成位元組碼程式,通過jvm將每條指令翻譯成不同的機器碼

,通過特定平臺執行。

4. JVM執行程式的過程

1) 載入.class檔案

2) 管理並分配記憶體

3) 執行垃圾收集

JRE(java執行時環境)由JVM構造的java程式的執行環,也是Java程式執行的環境,但是他同時一個作業系統的一個應用程式一個程序,

因此他也有他自己的執行的生命週期,也有自己的程式碼和資料空間。

JVM在整個jdk中處於最底層,負責於作業系統的互動,用來遮蔽作業系統環境,

提供一個完整的Java執行環境,因此也就虛擬計算機。

作業系統裝入JVM是通過jdk中Java.exe來完成,

通過下面4步來完成JVM環境:

1) 建立JVM裝載環境和配置

2) 裝載JVM.dll

3) 初始化JVM.dll並掛界到JNIENV(JNI呼叫介面)例項

4) 呼叫JNIEnv例項裝載並處理class類。

5. JVM的生命週期

1) JVM例項對應了一個獨立執行的java程式它是程序級別

a) 啟動。啟動一個Java程式時,一個JVM例項就產生了,任何一個擁有public static void

main(String[] args)函式的class都可以作為JVM例項執行的起點

b) 執行。main()作為該程式初始執行緒的起點,任何其他執行緒均由該執行緒啟動。JVM內部有兩種執行緒:守護執行緒和非守護執行緒,main()屬於非守護執行緒,守護執行緒通常由JVM自己使用,java程式也可以表明自己建立的執行緒是守護執行緒

c) 消亡。當程式中的所有非守護執行緒都終止時,JVM才退出;若安全管理器允許,程式也可以使用Runtime類或者System.exit()來退出

2) JVM執行引擎例項則對應了屬於使用者執行程式的執行緒它是執行緒級別的

6、JVM記憶體模型

(1)java程式碼具體執行過程如下圖,

(2)執行時資料區,即jvm記憶體結構圖如下圖

(3)執行時資料區儲存了哪些資料?

a) 程式計數器(PC暫存器)

由於在JVM中,多執行緒是通過執行緒輪流切換來獲得CPU執行時間的,因此,在任一具體時刻,一個CPU的核心只會執行一條執行緒中的指令,因此,為了能夠使得每個執行緒都線上程切換後能夠恢復在切 換 之前的程式執行位置,每個執行緒都需要有自己獨立的程式計數器,並且不能互相被幹擾,否則就會影響到程式的正常執行次序。因此,可以這麼說,程式計數器是每個執行緒所私有的。由於程式計數器中儲存的資料所佔空間的大小不會隨程式的執行而發生改變,

因此,對於程式計數器是不會發生記憶體溢位現象(OutOfMemory)的。

b) java棧

Java棧中存放的是一個個的棧幀,每個棧幀對應一個被呼叫的方法,在棧幀中包括區域性變量表(Local Variables) 、 運算元棧(Operand Stack) 、指向當前方法所屬的類的執行時常量池(執行時常量池的概念在方法區部分會談到) 的引用 (Reference to runtime constant pool)、方法返回地址(Return Address)和一些額外的附加資訊。當執行緒執行一個方法時,就會隨之建立一個對應的棧幀,並將建立的棧幀壓棧。當方法執行完畢之後,便會將棧幀出棧。

c)本地方法棧

本地方法棧與Java棧的作用和原理非常相似。區別只不過是Java棧是為執行Java方法服務的,而本地方法棧則是為執行本地方法(Native Method)服務的

d)堆

Java中的堆是用來儲存物件本身的以及陣列(陣列引用是存放在Java棧中的)。堆是被所有執行緒共享的,在JVM中只有一個堆。堆區劃分為老年代Tenured Generation)和新生代Young Generation),新生代劃分為一塊較大的Eden空間兩塊較小的Survivor空間(比例8:1:1),當物件在Survivor躲過一次GC的話,其物件年齡便會加1,預設情況下,物件年齡達到15時,就會移動到老年代中。一般來說,大物件會被直接分配到老年代,所謂的大物件是指需要大量連續儲存空間的物件,最常見的一種大物件就是大陣列,比如:byte[] data = newbyte[4*1024*1024]

e)方法區

與堆一樣,是被執行緒共享的區域。在方法區中,方法區中有一個永久代Permanet Generation),儲存了每個類的資訊(包括類的名稱、方法資訊、欄位資訊)、靜態變數、常量以及編譯器編譯後的程式碼等。

在Class檔案中除了類的欄位、方法、介面等描述資訊外,還有一項資訊是常量池,用來儲存編譯期間生成的字面量和符號引用。

在方法區中有一個非常重要的部分就是執行時常量池,它是每一個類或介面的常量池的執行時表示形式,在類和介面被載入到JVM後,對應的執行時常量池就被創建出來。當然並非Class檔案常量池中的內容才能進入執行時常量池,在執行期間也可將新的常量放入執行時常量池中,比如String的intern方法。

7、JVM記憶體溢位的情況

a) 程式計數器(Program Counter Register)

每條執行緒都有一個獨立的的程式計數器,各執行緒間的計數器互不影響,因此該區域是執行緒私有的。該記憶體區域是唯一一個在Java虛擬機器規範中沒有規定任何OOM(記憶體溢位:OutOfMemoryError)情況的區域。

b)Java虛擬機器棧(Java Virtual Machine Stacks)

在Java虛擬機器規範中,對這個區域規定了兩種異常情況:

1、如果執行緒請求的棧深度大於虛擬機器所允許的深度,將丟擲StackOverflowError異常。

2、如果虛擬機器在動態擴充套件棧時無法申請到足夠的記憶體空間,則丟擲OutOfMemoryError異常。

這兩種情況存在著一些互相重疊的地方:當棧空間無法繼續分配時,到底是記憶體太小,還是已使用的棧空間太大,其本質上只是對同一件事情的兩種描述而已。

在單執行緒的操作中,無論是由於棧幀太大,還是虛擬機器棧空間太小,當棧空間無法分配時,虛擬機器丟擲的都是StackOverflowError異常,而不會得到OutOfMemoryError異常。

而在多執行緒環境下,則會丟擲OutOfMemoryError異常。

c)堆Java Heap

Java Heap是Java虛擬機器所管理的記憶體中最大的一塊,它是所有執行緒共享的一塊記憶體區域。幾乎所有的物件例項和陣列都在這類分配記憶體。Java Heap是垃圾收集器管理的主要區域,因此很多時候也被稱為“GC堆”。

根據Java虛擬機器規範的規定,Java堆可以處在物理上不連續的記憶體空間中,只要邏輯上是連續的即可。如果在堆中沒有記憶體可分配時,並且堆也無法擴充套件時,將會丟擲OutOfMemoryError異常。

d)方法區域,又被稱為“永久代”,當方法區無法滿足記憶體分配需求時,將丟擲OutOfMemoryError異常。

相關推薦

java記憶體模型記憶體分配

1.什麼是jvm?(1)jvm是一種用於計算裝置的規範,它是一個虛構出來的機器,是通過在實際的計算機上模擬模擬各種功能實現的。(2)jvm包含一套位元組碼指令集,一組暫存器,一個棧,一個垃圾回收堆和一個儲存方法域。(3)JVM遮蔽了與具體作業系統平臺相關的資訊,使Java程式只需生成在Java虛擬機器上執行的

jvm記憶體模型記憶體分配

http://www.w2bc.com/Article/83700 1.什麼是jvm? (1)jvm是一種用於計算裝置的規範,它是一個虛構出來的機器,是通過在實際的計算機上模擬模擬各種功能實現的。 (2)jvm包含一套位元組碼指令集,一組暫存器,一個棧,一個垃圾回收堆

併發程式設計-(3)Java記憶體模型volatile

目錄 1、記憶體模型概念 2、多執行緒的特性 1.1、原子性 1.2、可見性 1.3、有序性 2、Java記憶體模型 2.1、JMM和JVM 2.2、Java記憶體模型(JMM) 2.2.1、案例 2

Java高併發程式設計學習筆記(三):Java記憶體模型執行緒安全

文章目錄 原子性 有序性 可見性 – 編譯器優化 – 硬體優化(如寫吸收,批操作) Java虛擬機器層面的可見性 Happen-Before規則(先行發生) 程式順序原則: volat

[高併發Java 三] Java記憶體模型執行緒安全

網上很多資料在描述Java記憶體模型的時候,都會介紹有一個主存,然後每個工作執行緒有自己的工作記憶體。資料在主存中會有一份,在工作記憶體中也有一份。工作記憶體和主存之間會有各種原子操作去進行同步。 但是由於Java版本的不斷演變,記憶體模型也進行了改變。本文只講述Jav

Java 記憶體模型硬體記憶體架構筆記

前言 可跟《主存存取和磁碟存取原理筆記》串著看 雜技 Java 記憶體模型(堆疊) Jvm 內部,Java 記憶體模型把記憶體分成了兩個部分:執行緒棧區和堆區: 棧區包含:執行緒執行資訊(執行緒棧),本地原始型別變數(boolean,byte, short, int, long, float, doubl

JAVA中堆疊記憶體分配原理

2、Java記憶體分配中的棧   在函式中定義的一些基本型別的變數資料和物件的引用變數都在函式的棧記憶體中分配。 當在一段程式碼塊定義一個變數時,Java在棧中為這個變數分配記憶體空間,當該變數退出其作用域後,Java會自動釋放掉為該變數所分配的記憶體空間,該記憶體空間可以立即被另作他用。    Java記憶

JVM記憶體結構、Java記憶體模型Java物件模型,你知道它們之間的區別嗎?

Java作為一種面向物件的,跨平臺語言,其物件、記憶體等一直是比較難的知識點。而且很多概念的名稱看起來又那麼相似,很多人會傻傻分不清楚。比如本文我們要討論的JVM記憶體結構、Java記憶體模型和Java物件模型,這就是三個截然不同的概念,但是很多人容易弄混。可以這樣說,很多高

實戰Java高併發程式設計之Java記憶體模型執行緒安全

Java記憶體模型 原子性: 是指一個操作是不可中斷的.即使多個執行緒一起執行的時候,一個操作一旦開始,就不會被其他執行緒干擾. 一般CPU的指令是原子的. Q:i++是原子操作嗎? A:不是.

java記憶體模型多執行緒

單個處理器的頻率越來越難以提升,因此人們轉而面向多處理器,這麼多年來致力於提高程式的執行效率,然而面向多核處理器的併發程式設計卻不是那麼的輕鬆,java在語言級別提供的多執行緒併發能力為我們編寫併發的程式提供了不少便利。但是本文並不打算講述如何編寫多執行緒併發程式,而是嘗試

Java記憶體區域記憶體模型

JVM的記憶體區域劃分由於Java程式是交由JVM執行的,所以我們在談Java記憶體區域劃分的時候事實上是指JVM記憶體區域劃分。在討論JVM記憶體區域劃分之前,先來看一下Java程式具體執行的過程:如上圖所示,首先Java原始碼檔案(.java字尾)會被Java編譯器編譯為

JVM記憶體結構、Java記憶體模型Java物件模型

Java作為一種面向物件的,跨平臺語言,其物件、記憶體等一直是比較難的知識點。而且很多概念的名稱看起來又那麼相似,很多人會傻傻分不清楚。比如本文要討論的JVM記憶體結構、Java記憶體模型和Java物件模型,這就是三個截然不同的概念,但是很多人容易弄混。 首先,這三個概念是完全不同的三個概念。本文主要目的是對

Java 記憶體模型 JVM 記憶體結構真不是一回事

這兩個概念估計有不少人會混淆,它們都可以說是 JVM 規範的一部分,但真不是一回事!它們描述和解決的是不同問題,簡單來說, Java 記憶體模型,描述的是多執行緒允許的行為 JVM 記憶體結構,描述的是執行緒執行所設計的記憶體空間 JVM 是什麼呢?它遮蔽了底層架構的差異性,是 Java 跨平臺的依據,也

Java多執行緒系列七)Java記憶體模型執行緒的三大特性

Java記憶體模型和執行緒的三大特性 多執行緒有三大特性:原子性、可見性、有序性 1、Java記憶體模型 Java記憶體模型(Java Memory Model ,JMM),決定一個執行緒對共享變數的寫入時,能對另一個執行緒可見。從抽象的角度來看,JMM定義了執行緒和主記憶體之間的抽象關係:執行緒之間的

JAVA記憶體模型Happens-Before規則

  前言 上一篇文章王子給大家介紹了併發程式設計中比較關心的三個核心問題,可見性、有序性和原子性。 今天我們繼續來探索併發程式設計的內容,聊一聊JAVA的記憶體模型和Happens-Before規則。   JAVA記憶體模型 這裡的JAVA記憶體模型指的不是我們JVM專欄中提到的記憶體分佈

C++PrimerPlus學習之記憶體模型名稱空間

標頭檔案 如果檔名包含在尖括號中,則C++編譯器將在儲存標準標頭檔案的主機系統的檔案系統的中查詢。如果檔名包含在雙引號中,則編譯器將在當前目錄下查詢。 使用條件編譯防止多次包含標頭檔案 #ifndef XXX_H_ #define XXX_H_ ... #en

java執行緒記憶體 java 重排序 java happens-before java 記憶體語義

執行緒之間的通訊機制有兩種:           共享記憶體:在共享記憶體的併發模型裡,執行緒之間共享程式的公共狀態,通過寫-讀記憶體中的公共狀態進行隱式通訊。      

【夾娃系列】java面試基礎知識儲備(¥2)——JVM記憶體劃分記憶體溢位異常的原因解決方法

JVM記憶體劃分和記憶體溢位 JVM記憶體劃分 記憶體溢位的異常和解決辦法 JVM記憶體劃分 堆:存放物件例項,被所有的執行緒共享的一塊區域。垃圾收集器管理的主要區域。 方法區:儲存虛擬機器載入的類資訊,常量,靜態變

java記憶體洩漏記憶體溢位

java記憶體洩漏和記憶體溢位 概念 a)記憶體洩露:被分配物件可達但無用 b)記憶體溢位:無法申請到足夠的記憶體而產生的錯誤 記憶體洩漏場景 a)建立和應用生命週期一樣的單例物件 b)建立匿名內部類的靜態物件 c)未關閉資源 d)長時間存在的集合容器中建立生命週期短

速記JVM記憶體模型垃圾回收策略

一、常用JVM引數 -Xms: 初始堆大小 -Xmx: 最大堆 -Xss: 棧容量 -PermSize: 方法區大小 -MaxPermSize: 最大方法區大小 -MaxDirectMemorySize: 最大直接記憶體大小 二、java虛擬機器基本結構   1.