轉自:http://www.cnblogs.com/evan2012/archive/2012/05/09/2489417.html html
1.jvm的內部體系結構淺析java
2.jvm的幾個運行時數據區域安全
3.jvm的內存溢出異常多線程
jvm全稱是Java Virtual Machine(java虛擬機)。它之因此被稱之爲是「虛擬」的,就是由於它僅僅是由一個規範來定義的抽象計算機。咱們平時常常使用的Sun HotSpot虛擬機只是其中一個具體的實現(另外還有BEA JRockit、IBM J9等等虛擬機)。在實際的計算機上經過軟件來實現一個虛擬計算機。與VMWare等相似軟件不一樣,你是看不到jvm的,它存在於內存。jvm
當啓動一個Java程序時,一個虛擬機實例也就誕生了。當該程序關閉退出,這個虛擬機實例也就隨之消亡。若是在同一臺計算機上同時運行三個Java程序,將獲得三個Java虛擬機實例。每一個Java程序都運行於它本身的Java虛擬機實例中。post
Java虛擬機在執行Java程序的過程當中會把它所管理的內存劃分爲若干個不一樣的數據區域。根據《Java虛擬機規範(第2版)》的規定,Java虛擬機所管理的內存將會包括如下幾個運行時數據區域,以下圖1所示。url
圖1 Java虛擬機的內部體系結構spa
下面先對圖中各部分作個簡單的說明:線程
1.class文件:虛擬機並不關心Class的來源是什麼語言,只要它符合Java class文件格式就能夠在Java虛擬機中運行。使用Java編譯器能夠把Java代碼編譯爲存儲字節碼的Class文件,使用JRuby等其餘語言的編譯器同樣能夠把程序代碼編譯成Class文件。設計
2.類裝載器子系統:負責查找並裝載Class 文件到內存,最終造成能夠被虛擬機直接使用的Java類型。
3.方法區:在類裝載器加載class文件到內存的過程當中,虛擬機會提取其中的類型信息,並將這些信息存儲到方法區。方法區用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。因爲全部線程都共享方法區,所以它們對方法區數據的訪問必須被設計爲是線程安全的。
4.堆:存儲Java程序建立的類實例。全部線程共享,所以設計程序時也要考慮到多線程訪問對象(堆數據)的同步問題。
5.Java棧:Java棧是線程私有的。每當啓動一個新線程時,Java虛擬機都會爲它分配一個Java棧。Java棧以幀爲單位保存線程的運行狀態。虛擬機只會直接對Java棧執行兩種操做:以幀爲單位的壓棧或出棧。當線程調用java方法時,虛擬機壓入一個新的棧幀到該線程的java棧中。當方法返回時,這個棧幀被從java棧中彈出並拋棄。一個棧幀包含一個java方法的調用狀態,它存儲有局部變量表、操做棧、動態連接、方法出口等信息。
6.程序計數器:一個運行中的Java程序,每當啓動一個新線程時,都會爲這個新線程建立一個本身的PC(程序計數器)寄存器。程序計數器的做用能夠看作是當前線程所執行的字節碼的行號指示器。字節碼解釋器工做時就是經過改變這個計數器的值來選取下一條須要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都須要依賴這個計數器來完成。若是線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;若是正在執行的是Natvie方法,這個計數器值則爲空(Undefined)。
7.本地方法棧:本地方法棧與虛擬機棧所發揮的做用是很是類似的,其區別不過是虛擬機棧爲虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則是爲虛擬機使用到的Native方法服務。任何本地方法接口都會使用某種本地方法棧。當線程調用Java方法時,虛擬機會建立一個新的棧幀並壓入Java棧。然而當它調用的是本地方法時,虛擬機會保持Java棧不變,再也不在線程的Java棧中壓入新的幀,虛擬機只是簡單地動態連接並直接調用指定的本地方法。若是某個虛擬機實現的本地方法接口是使用C鏈接模型的話,那麼它的本地方法棧就是C棧。
8.執行引擎:負責執行字節碼。方法的字節碼是由Java虛擬機的指令序列構成的。每一條指令包含一個單字節的操做碼,後面跟隨0個或多個操做數。執行引擎執行字節碼時,首先取得一個操做碼,若是操做碼有操做數,取得它的操做數。它執行操做碼和跟隨的操做數規定的動做,而後再取得下一個操做碼。這個執行字節碼的過程在線程完成前將一直持續。
相關的參考資料:
1.深刻Java虛擬機(原書第2版)
2.深刻理解Java虛擬機:JVM高級特性與最佳實踐
3.互聯網相關的文章