[看書筆記]《深入java虛擬機》——java體系結構(二)

java虛擬機的三種含義:
- 抽象的規范
- 一個具體的實現
- 一個運行中的虛擬機實例

---------------------java虛擬機的生命周期:
java虛擬機實例的天職就是負責運行一個java程序。
啟動一個java程序,一個虛擬機實例誕生了;程序關閉退出,虛擬機消亡。
有幾個java程序正在運行,就有幾個java虛擬機實例。每個java程序都運行在自己的java虛擬機實例中。

java虛擬機中有兩種線程:
- 守護線程:由虛擬機自己使用的(執行垃圾收集線程),java程序也可以把任何線程標記為守護線程。
- 非守護線程:main()這種。

非守護線程都終止時,虛擬機實例才自動退出。(也可以調用Runtime或System的exit()方法退出程序)。

---------------------java虛擬機的體系結構:
見同目錄第五章.Java虛擬機-體系結構圖!
方法區和堆是該虛擬機實例的所有線程共享的。
當虛擬機裝載一個class文件時,他會從這個class文件包含的二進制數據中解析類型信息,然后把這些類型信息放到方法區中。
當程序運行時,虛擬機會把所有該程序在運行時創建的對象都放到堆中。

每個新線程被創建時,他都將得到它自己的PC寄存器以及一個java棧(不是所有線程共享)。
java虛擬機為每個線程創建內存區,這些內存區域是私有的,任何線程都不能訪問另一個線程的PC寄存器或者java棧。
如果線程正在執行的是一個java方法(非本地方法),那么PC寄存器的值將總是指示下一條將被執行的指令。
java棧則總是存儲該線程中java方法調用的狀態(局部變量、被調用時傳進來的參數、返回值、運算的中間結果)

本地方法調用的狀態則是以某種依賴于具體實現的方式存儲在本地方法棧中,也可能在寄存器或者其他某些特定實現相關的內存區中。

---------------------棧幀(1):
java棧上由許多棧幀(幀)組成的,一個棧幀包含一個java方法調用的狀態。
當線程調用一個java方法時,虛擬機壓入一個新的棧幀到該線程的java棧中;當方法返回時,這個棧幀被從java棧中彈出并拋棄。

java虛擬機沒有寄存器,其指令集使用java棧來存儲中間數據(為了平臺無關性)。

---------------------類型數據
類型數據分為來那個中:
基本類型:float、double、byte、short、int、long、char、boolean
引用類型:reference(類引用、接口引用、數組引用)
注意:編譯成字節碼時boolean用int表示,

java虛擬機中,最基本的數據單元就是字,至少選擇32位作為字長。
運行時數據區的大部分內容,都是基于“字”這個抽象概念的。

---------------------類裝載器子系統:
類裝載器的裝載、連接和初始化:
- 裝載:查找并裝載類型的二進制數據
- 連接:執行驗證,準備,以及解析(可選)。
驗證:確保被導入類型的正確性。
準備:為靜態變量分配內存,并將其初始化為默認值。
解析:把類型中的符號引用轉換為直接引用。
- 初始化:把靜態變量初始化為正確初始值。

啟動類裝載器:
只要是符合java class文件格式的二進制文件,java虛擬機實現都必須能夠從中辨別并裝載器中的類和接口。每個java虛擬機實現必須有一個啟動類加載器來加載受信任的類,比如java API。

用戶自定義類裝載器:
用戶自定義的類裝載器是普通的java對象,它的類必須派生自java.lang.ClassLoader類。ClassLoader類中定義的方法為程序提供了訪問類裝載器機制的接口。
用戶自定義類裝載器和Class類的實例都放在內存中的堆區,而裝載的類型信息則都位于方法區。

ClassLoader類的四個通往java虛擬機的方法:
protected final Class defineClass(String name, byte data[], int offset, int length);
接收一個名為data[]的字節數組,并且在data[offset]到data[data+length]之間的二進制數據必須符合java class格式(表示一個新的可用類),name是該類型的全限定名,并將賦以默認的保護域。注意:該方法返回Class對象實例時表示指定的class文件已經被找到并裝載到了方法區(不一定連接和初始化)

protected final Class defineClass(String name, byte data[], int offset, int length,?
ProtectionDomain protectionDomain);
與前面一樣,只是,該類型的保護域將由它的protectionDomain參數指定。

protected final Class findSystemClass(String name);
接收一個字符串name(該類型的全限定名),用于啟動系統類裝載器(必須保證能啟動)。

protected final void resolveClass(Class c);
接收一個Class實例的引用作為參數,它將對該Class實例表示的類型執行連接動作(必須保證能執行連接動作)。

---------------------方法區:
所有線程都共享方法區,所以它們對方法區數據的訪問必須被設計為是線程安全的。
方法區的大小不必說固定的,虛擬機可以根據應用的需要動態調整。
方法區不必是連續的。
方法區也可以被垃圾收集。

類型信息:
對每個裝載的類型,虛擬機都會在方法區中存儲一下類型信息:
- 該類型全限定名
- 該類型的直接超類的全限定名(除非是Object類,沒有超類)
- 該類型是類類型還是接口類型
- 該類型的訪問修飾符(public、abstract、final的某個子集)
- 任何型直接超接口的全限定名的有序列表

- 該類型的常量池【核心】:所有常量的類型字段方法的符號引用(索引訪問)
- 字段信息:字段名,字段類型,字段修飾符
- 方法信息:方法名,返回類型,參數數量和類型(按序),方法修飾符
- 除了常量以外的靜態變量
- 一個到類ClassLoader的引用:跟蹤保存該類加載時所用的加載器的類別
- 一個到Class類的引用:虛擬機會創建一個相應的java.lang.Class類的實例

---------------------方法表:
方法表:類型數據結構
虛擬機為每個非抽象類都生成一個表,把它作為類信息的一部分保存在方法區。
方法表是一個數組,元素是所有它的實例可能被調用的實例方法的直接引用
,包括是超類直接繼承過來的方法。運行時可以通過方法表快速搜尋在對象中調用的實例方法。

---------------------堆:
java程序在運行時創建的所有類實例或數組都放在同一個堆中(要考慮線程同步問題)。
和方法區一樣,堆空間也不是連續的內存區。

---------------------數組:
數組的內部表示:
在java中,數組才是真正的對象
和其他對象一樣,數組總是存儲在堆中。
和其他對象一樣,數組也有一個與他們的類關聯的Class實例,所有具有相同維度和類型的數組都是同一個類的實例(不管數組的長度是多少)。

數組類的名稱由兩部分組成,每一維度用一個"["表示,用字符或字符串表示元素類型。如“[[Ljava/lang/Object”表示元素為Object的二維數組。

在堆中,每一個數組對象還必須要保存數組的長度、數組數據以及某些指向數組的類數據的引用。

---------------------程序計數器(PC寄存器):
每一個線程都有它自己的PC寄存器,它是在該線程啟動的時候創建的。
PC寄存器的大小是字長,因此能夠持有一個本地指針,也能夠持有一個returnAddress。當線程執行某個java方法時,PC寄存器的內容總是寫一條將被執行的指令的地址,這里的地址可以是個本地指針,也可以是在方法字節碼中相對于該方法其實指令的偏移量。如果該線程正在執行一個本地方法,此時PC寄存器的值是“undefined”。

---------------------Java棧:
每當啟動一個新線程時,java虛擬機都會為它分配一個java棧。
虛擬機智慧直接對java棧執行兩種操作:以幀為單位的壓棧或出棧。
每當線程調用一個java方法時,虛擬機都會在該java棧中壓入一個新幀。
java方法不管是正常返回還是拋異常中止,虛擬機都會將當前棧彈出java棧,然后釋放內存。

java棧和棧幀在內存中也不必說連續的。

---------------------棧幀(2):
棧幀的構成:
- 局部變量區:
是一個以字長為單位,從0開始計數的數組。字節碼指令通過從0開始的索引來使用其中的數據。
int、float、reference和returnAddress的值在數組中只占一項;
byte、short、char的值在存入數組前都被轉換成int,所以也只占一項;
boolean虛擬機不支持,用int來表示,所以也只占一項;
long、double的值在數組中占兩項(使用只要指出第一項索引值)。
局部變量區包含對應的方法參數和局部變量。
按參數的順序來存入局部變量數組中。真正的局部變量順序任意。

- 操作數棧:
是一個以字節為單位的數組(不是通過索引來訪問),是通過標準的棧操作(壓棧和出棧)來訪問。
存儲的數據類型和局部變量區的一樣。
虛擬機把操作數棧作為他的工作區,大多數指令都要從這里彈出數據,執行計算,然后把結果壓回到操作數棧中。

- 幀數據區:
常量池解析、正常方法返回、異常派發機制。
每當虛擬機要執行某個需要用到常量池數據的指令時,它都會通過幀數據區中指向常量池的指針來訪問它。
幀數據區還要幫助虛擬機處理java方法的正常結束或異常中止:
如果正常結束:虛擬機必須恢復發起調用的方法的(上一個)棧幀,調用完成方法的指令的下一個指令。如果有返回值,虛擬機將把返回值壓倒發 起調用的方法的操作數棧。
如果拋出異常,根據幀數據區的異常表來處理。如果有catch語句,就會交給catch中的代碼,如果沒有,則立即異常中止。

---------------------本地方法棧:
當線程調用本地方法時,虛擬機會保持java棧不變,不再在線程的java棧中壓入新的幀,虛擬機只是簡單地動態連接并直接調用指定的本地方法。

就像其他運行時內存區一樣,本地方法棧占用的內存區也不必說固定大小的,它可以根據需要動態擴展或者收縮。

---------------------執行引擎:
任何java虛擬機實現的核心都是它的執行引擎。
在java虛擬機規范中,執行引擎的行為使用指令集來定義。
作為運行時實例的執行引擎就是一個線程。
運行中java程序的每一個線程都是一個獨立的虛擬機執行引擎的實例。從生命周期的開始到結束,它要么在執行字節碼,要么在執行本地方法。

本文轉自天天_byconan博客園博客,原文鏈接:http://www.cnblogs.com/tiantianbyconan/archive/2013/02/24/2923987.html,如需轉載請自行聯系原作者

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540454.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540454.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540454.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉載] 【零基礎學爬蟲】python中的yield詳解

參考鏈接: 什么時候在Python中使用yield而不是return python中的yield功能比較強大,什么意思呢?如果一個函數f內使用了yield關鍵詞,那么該函數就可以這樣使用: for item in f(***): **** 也就是包含yield關鍵詞的函…

全新的membership框架Asp.net Identity(1)——.Net membership的歷史

在Asp.net上,微軟的membershop框架經歷了Asp.net membership到Asp.net simple membership,再到現在的Asp.net Identity. 每一次改變,都使得驗證框架更加的適應變化和可定制。這篇文章是Asp.net Identity系列的開篇,主要就membersh…

c語言100位整數變量聲明_C ++程序動態聲明一個整數變量并打印其內存地址

c語言100位整數變量聲明Here, we will learn how we can declare an integer variable dynamically and how to print address of declared memory block? 在這里,我們將學習如何動態聲明整數變量,以及如何打印聲明的內存塊的地址? In C pr…

[轉載] python 函數返回多個值

參考鏈接: 在Python中返回多個值 (廖雪峰Python教程學習筆記) 函數體內部的語句在執行時,一旦執行到return,函數就執行完畢,并將結果返回。 如果沒有return語句,函數執行完畢后也會返回結果…

二.編寫第一個c#程序(注釋,命名空間,類,Main方法,標識符,關鍵字,輸入,輸出語句,)...

復習編寫一個控制臺應用程序,目標是在控制臺輸出“Hello World” 1.第一步,打開Visual Studio 2012以上版本(我用的是VS 2015),打開完成后出現以下界面 2.第二步,這時候就要新建一個解決方案了,創建解決方案可以直接點…

[轉載] Python中定義函數,循環語句,條件語句

參考鏈接: Python中的局部函數 由于日常程序流中主要是三種結構:順序,循環,條件,且往往需要自定義函數再調用, 因此今天想學習一下Python中關于定義函數、循環語句和條件語句的寫法。 1.定義函數 區…

node oauth2驗證_如何設置和使用護照OAuth Facebook身份驗證(第1部分)| Node.js

node oauth2驗證In my last articles, we looked at the implementation of the passport-local authentication strategy. We also looked at the various requirements to get started with the login form. 在上一篇文章中,我們介紹了護照本地身份驗證策略的實現…

vue2.0 引用qrcode.js實現獲取改變二維碼的樣式

vue代碼 <template><div class"qart"><div id"qrcode" ref"qrcode"></div><input type"text" id"getval" value"" placeholder"修改這個值改變二維碼"></div> <…

[轉載] Python列表排序 list.sort方法和內置函數sorted

參考鏈接&#xff1a; Python中的函數 Python列表排序 list.sort方法和內置函數sorted 很多時候我們獲取到一個列表后,這個列表并不滿足我們的需求,我們需要的是一個有特殊順序的列表. 這時候就可以使用list.sort方法和內置函數sorted,本文就是介紹list.sort方法和sorted內…

Java Thread類最終同步的void join(long time_in_ms)方法,帶有示例

線程類最終同步無效連接(long time_in_ms) (Thread Class final synchronized void join(long time_in_ms)) This method is available in package java.lang.Thread.join(long time_in_ms). 軟件包java.lang.Thread.join(long time_in_ms)中提供了此方法。 join(long time_in_…

RYU控制器安裝`

2019獨角獸企業重金招聘Python工程師標準>>> 同樣是參考了http://linton.tw/2014/02/11/note-how-to-set-up-ryu-controller-with-gui-component/的內容。 1. 由于Ubuntu中自帶有Python&#xff0c;因此直接開始安裝pip apt-get install python-pip apt-get i…

[轉載] mac開發者,你不得不知道的環境變更設置方法(如Java的環境變更 source命令 )

參考鏈接&#xff1a; 設置Java環境 Mac是基于Unix的&#xff0c;所有先來幾個常識與命令&#xff1a; Unix中雙引號單引號反引號(" )的區別 Unix中雙引號起到“弱引用”的作用:被引用的字符大部分被按照字符字面的意思解釋執行&#xff0c;除了了$,\,字符除外。 [因…

人形機器人正在美國史密森尼博物館中擔任導游的工作

Te article has been removed, please visit IncludeHelps home page for more articles 該文章已被刪除&#xff0c;請訪問IncludeHelp的主頁以獲取更多文章翻譯自: https://www.includehelp.com/News/a-humanoid-robot-is-doing-the-job-of-a-guide-in-the-smithsonian-museu…

normalizr API

APInormalizedenormalizeschemaArrayEntityObjectUnionValuesnormalize(data, schema)Normalizes input data per the schema definition provided. 根據提供的schema定義規范化輸入數據。data: required Input JSON (or plain JS object) data that needs normalization.schem…

[轉載] 【Java】基礎06:HelloWorld入門程序

參考鏈接&#xff1a; 從Hello World示例開始Java編程 HelloWorld它的中文意思是&#xff1a;“你好&#xff0c;世界”。 仿佛代表著計算機對世界說出來的第一句話&#xff0c;因為它簡潔實用&#xff0c;所以被作為入門程序廣泛使用。 Java程序開發三步驟&#xff1a;編…

[轉載] Java中的命名參數

參考鏈接&#xff1a; Java命名約定 創建具有許多參數的方法是一個主要的缺點。 每當需要創建這樣的方法時&#xff0c;就在空氣中聞一聞&#xff1a;這是代碼的味道。 強化單元測試&#xff0c;然后進行重構。 沒有借口&#xff0c;沒有屁股。 重構&#xff01; 使用構建器模…

[轉載] JVM(一):JVM體系結構詳解

參考鏈接&#xff1a; JVM如何工作–JVM體系結構 JVM簡介 JVM是Java程序得以運行的平臺&#xff0c;也是Java程序可以跨平臺的底層支撐&#xff0c;從整體上來看&#xff0c;JVM的主要功能可以分為加載和執行兩大塊。其中類加載器負責.class文件的尋址與加載&#xff0…

數據庫連接池的設計思路及java實現

2019獨角獸企業重金招聘Python工程師標準>>> connectionPool.DBConnectionManager [java] view plain copy package connectionPool; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; i…

[轉載] java虛擬機 jvm 出入java棧 棧空間內存分配

參考鏈接&#xff1a; Java虛擬機(JVM)堆棧區域 java棧空間是一塊線程私有的內存空間&#xff0c;java堆和程序數據密切相關&#xff0c;那么java棧就是和線程執行密切相關。線程最基本的執行行為就是函數的調用。每次函數調用其實是通過java棧傳遞數據的。 數據結構中的棧的…

SVN命令行更新代碼

命令列表 svn help查看幫助信息 Available subcommands: add auth blame (praise, annotate, ann) cat changeli…