日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java三年,Java开发三年,你不得不了解的JVM(一)

發(fā)布時間:2023/12/10 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java三年,Java开发三年,你不得不了解的JVM(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基本概念:

JVM 是可運行 Java 代碼的假想計算機 ,包括一套字節(jié)碼指令集、一組寄存器、一個棧、一個垃圾回收,堆 和 一個存儲方法域。JVM 是運行在操作系統(tǒng)之上的,它與硬件沒有直接的交互。

運行過程:

我們都知道

Java

源文件,通過編譯器,能夠生產(chǎn)相應的

.Class

文件,也就是字節(jié)碼文件,

而字節(jié)碼文件又通過

Java

虛擬機中的解釋器,編譯成特定機器上的機器碼。

也就是如下:

Java

源文件—

->

編譯器—

->

字節(jié)碼文件

②字節(jié)碼文件—

->JVM

->

機器碼

每一種平臺的解釋器是不同的,但是實現(xiàn)的虛擬機是相同的,這也就是

Java

為什么能夠

跨平臺的原因了,當一個程序從開始運行,這時虛擬機就開始實例化了,多個程序啟動就會

存在多個虛擬機實例。程序退出或者關(guān)閉,則虛擬機實例消亡,多個虛擬機實例之間數(shù)據(jù)不

能共享。

線程

這里所說的線程指程序執(zhí)行過程中的一個線程實體。JVM允許一個應用并發(fā)執(zhí)行多個線程。Hotspot JVM 中的Java 線程與原生操作系統(tǒng)線程有直接的映射關(guān)系。當線程本地存儲、緩沖區(qū)分配、同步對象、棧、程序計數(shù)器等準備好以后,就會創(chuàng)建一個操作系統(tǒng)原生線程。Java 線程結(jié)束,原生線程隨之被回收。操作系統(tǒng)負責調(diào)度所有線程,并把它們分配到任何可用的CPU 上。當原生線程初始化完畢,就會調(diào)用Java 線程的run() 方法。當線程結(jié)束時,會釋放原生線程和Java 線程的所有資源。

HotspotJVM

后臺運行的系統(tǒng)線程主要有下面幾個:

JVM內(nèi)存區(qū)域

JVM 內(nèi)存區(qū)域主要分為線程私有區(qū)域【程序計數(shù)器、虛擬機棧、本地方法區(qū)】、線程共享區(qū)域【JAVA堆、方法區(qū)】、直接內(nèi)存。

線程私有數(shù)據(jù)區(qū)域生命周期與線程相同, 依賴用戶線程的啟動/結(jié)束而創(chuàng)建/銷毀(在Hotspot VM內(nèi), 每個線程都與操作系統(tǒng)的本地線程直接映射, 因此這部分內(nèi)存區(qū)域的存/否跟隨本地線程的生/死對應)。線程共享區(qū)域隨虛擬機的啟動/關(guān)閉而創(chuàng)建/銷毀。直接內(nèi)存并不是JVM運行時數(shù)據(jù)區(qū)的一部分,但也會被頻繁的使用: 在JDK 1.4引入的NIO提供了基于Channel與Buffer的IO方式, 它可以使用Native函數(shù)庫直接分配堆外內(nèi)存, 然后使用DirectByteBuffer對象作為這塊內(nèi)存的引用進行操作(詳見:Java I/O 擴展), 這樣就避免了在Java堆和Native堆中來回復制數(shù)據(jù), 因此在一些場景中可以顯著提高性能。

程序計數(shù)器(線程私有)

一塊較小的內(nèi)存空間, 是當前線程所執(zhí)行的字節(jié)碼的行號指示器,每條線程都要有一個獨立的程序計數(shù)器,這類內(nèi)存也稱為“線程私有”的內(nèi)存。

正在執(zhí)行

java

方法的話,計數(shù)器記錄的是虛擬機字節(jié)碼指令的地址(當前指令的地址)。如

果還是

Native

方法,則為空。

這個內(nèi)存區(qū)域是唯一一個在虛擬機中沒有規(guī)定任何

OutOfMemoryError

情況的區(qū)域。

虛擬機棧(線程私有)

是描述java方法執(zhí)行的內(nèi)存模型,每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀(StackFrame)用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。每一個方法從調(diào)用直至執(zhí)行完成的過程,就對應著一個棧幀在虛擬機棧中入棧到出棧的過程。

棧幀(Frame)是用來存儲數(shù)據(jù)和部分過程結(jié)果的數(shù)據(jù)結(jié)構(gòu),同時也被用來處理動態(tài)鏈接(Dynamic Linking)、方法返回值和異常分派(Dispatch Exception)。棧幀隨著方法調(diào)用而創(chuàng)建,隨著方法結(jié)束而銷毀——無論方法是正常完成還是異常完成(拋出了在方法內(nèi)未被捕獲的異常)都算作方法結(jié)束。

本地方法區(qū)(線程私有)

本地方法區(qū)和Java Stack作用類似, 區(qū)別是虛擬機棧為執(zhí)行Java方法服務, 而本地方法棧則為Native方法服務,如果一個VM實現(xiàn)使用C-linkage模型來支持Native調(diào)用,那么該棧將會是一個C棧,但HotSpot VM直接就把本地方法棧和虛擬機棧合二為一。

堆(Heap-線程共享)-運行時數(shù)據(jù)區(qū)

是被線程共享的一塊內(nèi)存區(qū)域,創(chuàng)建的對象和數(shù)組都保存在Java堆內(nèi)存中,也是垃圾收集器進行垃圾收集的最重要的內(nèi)存區(qū)域。由于現(xiàn)代VM采用分代收集算法,因此Java堆從GC的角度還可以細分為:新生代(Eden區(qū)、From Survivor區(qū)和To Survivor區(qū))和老年代。

方法區(qū)/永久代(線程共享)

即我們常說的

永久代

(Permanent Generation)

,

用于存儲

JVM

加載的類信息

常量

態(tài)變量

即時編譯器編譯后的代碼

等數(shù)據(jù)

.HotSpotVM

GC

分代收集擴展至方法區(qū)

,

使用

Java

堆的永久代來實現(xiàn)方法區(qū)

,

這樣

HotSpot

的垃圾收集器就可以像管理

Java

堆一樣管理這部分內(nèi)存

,

而不必為方法區(qū)開發(fā)專門的內(nèi)存管理器

(

永久帶的內(nèi)存回收的主要目標是針對

常量池的回收

類型

的卸載

,

因此收益一般很小

)

運行時常量池

(

Runtime Constant Pool

)是方法區(qū)的一部分。

Class

文件中除了有類的版

本、字段、方法、接口等描述等信息外,還有一項信息是常量池

(

Constant Pool Table

),用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容將在類加

載后存放到方法區(qū)的運行時常量池中。

Java

虛擬機對

Class

文件的每一部分(自然也包括常量

池)的格式都有嚴格的規(guī)定,每一個字節(jié)用于存儲哪種數(shù)據(jù)都必須符合規(guī)范上的要求,這樣才會

被虛擬機認可、裝載和執(zhí)行。

總結(jié)

以上是生活随笔為你收集整理的java三年,Java开发三年,你不得不了解的JVM(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。