JVM工作原理和特點主要是指操作系統裝入JVM是通過jdk中Javaexe來完成通過下面步來完成JVM環境
創建JVM裝載環境和配置
裝載JVMdll
初始化JVMdll並掛界到JNIENV(JNI調用接口)實例
調用JNIEnv實例裝載並處理class類
在我們運行和調試Java程序的時候經常會提到一個JVM的概念JVM是Java程序運行的環境但是他同時一個操作系統的一個應用程序一個進程因此他也有他自己的運行的生命周期也有自己的代碼和數據空間
首先來說一下JVM工作原理中的jdk這個東西不管你是初學者還是高手是jee程序員還是jse程序員jdk總是在幫我們做一些事情我們在了解Java之前首先大師們會給我們提供說jdk這個東西它在Java整個體系中充當著什麼角色呢?我很驚歎sun大師們設計天才能把一個如此完整的體系結構化的如此完美jdk在這個體系中充當一個生產加工中心產生所有的數據輸出是所有指令和戰略的執行中心本身它提供了Java的完整方案可以開發目前Java能支持的所有應用和系統程序這裡說一個問題大家會問那為什麼還有jmejee這些東西這兩個東西目的很簡單分別用來簡化各自領域內的開發和構建過程jdk除了JVM之外還有一些核心的API集成API用戶工具開發技術開發工具和API等組成
好了廢話說了那麼多來點於主題相關的東西吧JVM在整個jdk中處於最底層負責於操作系統的交互用來屏蔽操作系統環境提供一個完整的Java運行環境因此也就虛擬計算機 操作系統裝入JVM是通過jdk中Javaexe來完成通過下面步來完成JVM環境
創建JVM裝載環境和配置
裝載JVMdll
初始化JVMdll並掛界到JNIENV(JNI調用接口)實例
調用JNIEnv實例裝載並處理class類
一.JVM裝入環境JVM提供的方式是操作系統的動態連接文件.既然是文件那就一個裝入路徑的問題Java是怎麼找這個路徑的呢?當你在調用Java test的時候操作系統會在path下在你的Javaexe程序Javaexe就通過下面一個過程來確定JVM的路徑和相關的參數配置了.下面基於Windows的實現的分析.
首先查找jre路徑Java是通過GetApplicationHome api來獲得當前的Javaexe絕對路徑c:\jsdk_\bin\Javaexe那麼它會截取到絕對路徑c:\jsdk_\判斷c:\jsdk_\bin\Javadll文件是否存在如果存在就把c:\jsdk_\作為jre路徑如果不存在則判斷c:\jsdk_\jre\bin\Javadll是否存在如果存在這c:\jsdk_\jre作為jre路徑.如果不存在調用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\當前JRE版本號\JavaHome的路徑為jre路徑
然後裝載JVMcfg文件JRE路徑+\lib+\ARCH(CPU構架)+\JVMcfgARCH(CPU構架)的判斷是通過Java_mdc中GetArch函數判斷的該函數中windows平台只有兩種情況WIN的ia其他情況都為i以我的為例C:\jsdk_\jre\lib\i\JVMcfg主要的內容如下
client KNOWN
server KNOWN
hotspot ALIASED_TO client
classic WARN
native ERROR
green ERROR
在我們的jdk目錄中jre\bin\server和jre\bin\client都有JVMdll文件存在而Java正是通過JVMcfg配置文件來管理這些不同版本的JVMdll的.通過文件我們可以定義目前jdk中支持那些JVM前面部分(client)是JVM名稱後面是參數KNOWN表示JVM存在ALIASED_TO表示給別的JVM取一個別名WARN表示不存在時找一個JVM替代ERROR表示不存在拋出異常.在運行Java XXX是Javaexe會通過CheckJVMType來檢查當前的JVM類型Java可以通過兩種參數的方式來指定具體的JVM類型一種按照JVMcfg文件中的JVM名稱指定第二種方法是直接指定它們執行的方法分別是Java JJava XXaltJVM=或Java JXXaltJVM=如果是第一種參數傳遞方式CheckJVMType函數會取參數J後面的JVM名稱然後從已知的JVM配置參數中查找如果找到同名的則去掉該JVM名稱前的直接返回該值而第二種方法會直接返回XXaltJVM=或JXXaltJVM=後面的JVM類型名稱如果在運行Java時未指定上面兩種方法中的任一一種參數CheckJVMType會取配置文件中第一個配置中的JVM名稱去掉名稱前面的返回該值CheckJVMType函數的這個返回值會在下面的函數中匯同jre路徑組合成JVMdll的絕對路徑如果沒有指定這會使用JVMcfg中第一個定義的JVM可以通過set _Java_LAUNCHER_DEBUG=在控制台上測試.
最後獲得JVMdll的路徑JRE路徑+\bin+\JVM類型字符串+\JVMdll就是JVM的文件路徑了但是如果在調用Java程序時用XXaltJVM=參數指定的路徑path就直接用path+\JVMdll文件做為JVMdll的文件路徑.
二裝載JVMdll
通過第一步已經找到了JVM的路徑Java通過LoadJavaVM來裝入JVMdll文件.裝入工作很簡單就是調用Windows API函數
LoadLibrary裝載JVMdll動態連接庫.然後把JVMdll中的導出函數JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs掛接到InvocationFunctions變量的CreateJavaVM和GetDefaultJavaVMInitArgs函數指針變量上JVMdll的裝載工作宣告完成
三初始化JVM獲得本地調用接口這樣就可以在Java中調用JVM的函數了.調用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法獲得JNIEnv結構的實例.
四運行Java程序.
Java程序有兩種方式一種是jar包一種是class 運行jarJava jar XXXjar運行的時候Javaexe調用GetMainClassName函數該函數先獲得JNIEnv實例然後調用Java類JavautiljarJarFileJNIEnv中方法getManifest()並從返回的Manifest對象中取getAttributes(MainClass)的值即jar包中文件METAINF/MANIFESTMF指定的MainClass的主類名作為運行的主類之後main函數會調用Javac中LoadClass方法裝載該主類(使用JNIEnv實例的FindClass)main函數直接調用Javac中LoadClass方法裝載該類如果是執行class方法main函數直接調用Javac中LoadClass方法裝載該類
然後main函數調用JNIEnv實例的GetStaticMethodID方法查找裝載的class主類中
public static void main(String[] args)方法並判斷該方法是否為public方法然後調用JNIEnv實例的
CallStaticVoidMethod方法調用該Java類的main方法
JVM工作原理和特點介紹到這裡
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26046.html