本文目錄一覽:
JVM的組成和運行原理是什麼?
JVM是Java Virtual Machine(Java虛擬機)的縮寫。
1、JVM的組成:
JVM 由類加載器子系統、運行時數據區、執行引擎以及本地方法接口組成。
2、JVM的運行原理:
JVM是java的核心和基礎,在java編譯器和os平台之間的虛擬處理器。它是一種基於下層的操作系統和硬件平台並利用軟件方法來實現的抽象的計算機,可以在上面執行java的位元組碼程序。java編譯器只需面向JVM,生成JVM能理解的代碼或位元組碼文件。Java源文件經編譯器,編譯成位元組碼程序,通過JVM將每一條指令翻譯成不同平台機器碼,通過特定平台運行。
簡述jvm工作原理
Java是一種技術,它由四方面組成:Java編程語言、Java類文件格式、Java虛擬機和Java應用程序接口(Java API)。
運行期環境代表着Java平台,開發人員編寫Java代碼(.java文件),然後將之編譯成位元組碼(.class文件),再然後位元組碼被裝入內存,一旦位元組碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。
Java平台由Java虛擬機和Java應用程序接口搭建,Java語言則是進入這個平台的通道,用Java語言編寫並編譯的程序可以運行在這個平台上。
在Java平台的結構中, 可以看出,Java虛擬機(JVM) 處在核心的位置,是程序與底層操作系統和硬件無關的關鍵。它的下方是移植接口,移植接口由兩部分組成:適配器和Java操作系統, 其中依賴於平台的部分稱為適配器;JVM 通過移植接口在具體的平台和操作系統上實現;在JVM 的上方是Java的基本類庫和擴展類庫以及它們的API, 利用Java API編寫的應用程序(application) 和小程序(Java applet) 可以在任何Java平台上運行而無需考慮底層平台, 就是因為有Java虛擬機(JVM)實現了程序與操作系統的分離,從而實現了Java 的平台無關性。
JVM在它的生存周期中有一個明確的任務,那就是運行Java程序,因此當Java程序啟動的時候,就產生JVM的一個實例;當程序運行結束的時候,該實例也跟着消失了。下面我們從JVM的體系結構和它的運行過程這兩個方面來對它進行比較深入的研究。
1、Java虛擬機的體系結構
·每個JVM都有兩種機制:
①類裝載子系統:裝載具有適合名稱的類或接口
②執行引擎:負責執行包含在已裝載的類或接口中的指令
·每個JVM都包含:
方法區、Java堆、Java棧、本地方法棧、指令計數器及其他隱含寄存器
2、Java代碼編譯和執行的整個過程
也正如前面所說,Java代碼的編譯和執行的整個過程大概是:開發人員編寫Java代碼(.java文件),然後將之編譯成位元組碼(.class文件),再然後位元組碼被裝入內存,一旦位元組碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。
(1)Java代碼編譯是由Java源碼編譯器來完成,也就是Java代碼到JVM位元組碼(.class文件)的過程。
2)Java位元組碼的執行是由JVM執行引擎來完成
Java代碼編譯和執行的整個過程包含了以下三個重要的機制:
·Java源碼編譯機制
·類加載機制
·類執行機制
(1)Java源碼編譯機制
Java 源碼編譯由以下三個過程組成:
①分析和輸入到符號表
②註解處理
③語義分析和生成class文件
最後生成的class文件由以下部分組成:
①結構信息:包括class文件格式版本號及各部分的數量與大小的信息
②元數據:對應於Java源碼中聲明與常量的信息。包含類/繼承的超類/實現的接口的聲明信息、域與方法聲明信息和常量池
③方法信息:對應Java源碼中語句和表達式對應的信息。包含位元組碼、異常處理器表、求值棧與局部變量區大小、求值棧的類型記錄、調試符號信息
(2)類加載機制 JVM的類加載是通過ClassLoader及其子類來完成的
深入理解jvm原理之逃逸分析
最近一直在學習Java虛擬機原理,覺得有意思的地方就寫個文章記錄下來。優勝劣汰是自然界的發展,適用到Java虛擬機也不為過,jvm過了生存下去,一直在自我進化,Java虛擬機也在不停的進化和優化,有的是基於執行代碼的優化,例如指令重排序等等;有的是基於分析技術,例如關係分析或者逃逸分析等等,今天就重點介紹一下jvm中的分析技術優化—逃逸分析;內容大部分源自於《深入理解Java虛擬機》;
逃逸分析一般分為兩種:一種基本行為就是分析對象的動態作用域,當一個對象在方法中定義後,它可能被外部的方法所引用,例如作為調用參數傳入了其他對象中,稱為方法逃逸;甚至被外部線程所引用,例如賦值給變量或可以在其他線程中訪問的變量,這種優化行為稱為線程逃逸;
概念歸概念,最終效果怎麼樣,肯定還需要是騾子是馬拉出來遛遛,總牛的理論需要落地檢驗,說程序員的話,也就是一個對象不會逃逸到方法或者線程之外後,這個變量會進行一些高效的優化;實現方式一般有下面幾種;
棧上分配:無論是C#還是Java的程序員,大家都知道,對象會創建在Java堆上,而Java堆中的對象對線程(Java線程)是共享和可見的,而虛擬機的垃圾回收就是回收對象不再適用的對象,無論哪種垃圾回收器,都需要需要篩選和整理可回收的對象,回收和整理要耗費很長時間,如果確定一個方法不會逃逸出方法之外,那就讓這個對象直接分配在棧上,而對象所佔用的空間也會隨着幀棧的出棧而銷毀,垃圾回收系統的壓力會就變的小了;
消除同步:線程同步本身就是一個相對耗時的過程(至於為什麼耗時,可以查詢用戶線程和內核線程相關知識),如果確認一個對象不會被其他線程訪問;那麼變量的讀寫就不會和其他線程競爭,對於這種變量實施的同步可以消除;
標量替換:標量又稱scalar是指一個數據已經無法再分解成更小的數據來表示了,Java虛擬機中的原始數據例如int,long,等值類型以及reference類型,都不能再進一步分解,他們就可以稱為標量,相對的,它們如果可以繼續分解,那就是稱為聚合量又稱Aggregate,Java對象就是典型的聚合量,如果把一個對象拆散,根據程序訪問情況,將其使用到的成員變量類型變成基本類型代替,如果jvm逃逸分析中發現這個對象不會外部對象使用,那程序執行的就不會創建該對象,為改為創建它的若干個被這個方法使用的成員變量來代替(棧上創建的數據,又很大的概率會被jvm分配至物理機的高速寄存器中存儲),這個也為後續進一步的優化創造了條件;
逃逸分析很多優勢還在陸陸續續發現,Java8已經默認開啟了逃逸分析, -XX:+DoEscapeAnalysis 開啟或者關閉這個選項;都是幹活,後續上帶么和截圖來驗證一下;
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/285236.html