JVM虛擬機個人總結(一)

千里之堤始於足下,想要學好Java,需要大致瞭解JVM是如何運行的!
先說一些廢話,跟正文無關,不想被嘮叨的同學可以直接跳過。不知道大家剛學Java是怎麼過來的,我剛學Java的時候,就是老師教我一步一步的走,最後能跑出一個Hello World的一個實例。但是中途爲什麼這麼做,這麼做的意義是什麼,我一概不知,只是知其然,不知其所以然。我對其內部如何實現的,爲何這麼實現感到非常好奇,所以在接下來的日子裏,我將學習JVM,每週寫一次總結,這是我給自己的目標!

好,那麼廢話不多說,接下來開始正文。首先我需要要確定學習JVM我要瞭解到什麼程度,帶着目的的去學習。作爲一個已經畢業在開發的人來說,在日常工作中,其實了不瞭解JVM對於只是碼代碼的你我沒有差別,也就是說你懂或不懂並不影響你實現的工作中的表現。所以如果你甘於這樣,那麼其實了不瞭解JVM都無所謂。但是我認爲做技術的人,都帶有那麼一點點不安分的心,不想過像老師等職業一般朝九晚五的生活,所以爲了提高技術,那麼學習JVM就很有必要了。

那麼要瞭解到什麼程度呢?對於我現在剛畢業的小白來講,我打算了解JVM是如何跑動一個程序的,內部的架構是怎樣的等等,但是我個人認爲如果我只是想做架構師,而不是底層開發人員,其實JVM你不必瞭解的太過清晰,只需要在工作上使用的地方瞭解這麼做是怎麼實現的就行了。好,接下來進入我對JVM的總結:

首先需要確定Java的體系結構是怎樣的?他由什麼所組成?
第一:Java的程序設計語言(其實就是在工作中你打的源代碼,.java文件中的內容)
第二:Java class文件格式(就是通過javac等編譯器編譯出的.class文件,是一系列字節碼)
第三:Java虛擬機(這個我不就多做介紹了)
第四:Java應用編程接口(就是Java核心API,例如:java.util.*包下的代碼等等)

那麼Java要運行一個程序需要經歷哪些步驟呢?
第一步:用Java編程語言編寫源代碼
第二步:用Java編譯器編譯成class文件
第三步:通過Java虛擬機運行class文件
這裏寫圖片描述

Java虛擬機的主要任務是什麼?
裝載class文件,並且執行其中的字節碼。Java虛擬機中包含類加載器,他可以裝載Java class文件。Java API只有程序運行需要的那些類纔會被加載,字節碼由執行引擎來執行。

那麼執行引擎又是什麼?
不同的Java虛擬機中執行引擎可能會非常的不同。最簡單的執行殷勤就是一次性解釋字節碼,另一種執行引擎更快,但是更加消耗內存,叫做即使編譯器。在這種情況下,第一次執行的字節碼會被編譯成本地字節碼,編譯出的本地機器代碼會被緩存,當方法以後被調用的時候可以重用。第三種執行引擎是自適應優化器。在這種方法下,虛擬機開始的時候解釋字節碼,但是運行中會監視運行中程序的活動,並且記錄下使用頻繁的代碼段。程序運行的時候,虛擬機只把那些活動最頻繁的代碼段編譯成本地代碼,其他不頻繁的代碼由虛擬機繼續解釋。

接下來來講一下Java的自豪點:平臺無關性
Java對平臺無關性是如何支持的呢?
1.Java平臺:Java平臺扮演一個Java程序與其下硬件和操作系統之間的緩衝角色,無論Java程序被部署到何處,它只需要與Java平臺進行交互,而不需要擔心底層的硬件和操作系統。
2.Java語言:保證基本數據類型在所有平臺上都一致性(像C或C++語言,基本整數類型int是由它的佔位寬度決定的,而它的佔位寬度是由它的目標平臺決定的)
3.Java class文件:Java class文件可以在任何平臺上創建,也可以被任何平臺的Java虛擬機裝入並運行,與Java虛擬機所在的平臺是無關的。

影響Java平臺無關性有哪些因素?
1.Java平臺的部署(即每個平臺都要安裝JVM虛擬機)
2.Java平臺的版本(需要對應正確的Java版本,比如現在Java 8的新特性,Java 7就沒用)
3.本地方法(你的程序是否調用了本地方法,如果是則與平臺相關)
4.非標準運行時庫(如果調用非標準運行時庫,需要知道他是否調用了本地方法)
5.對虛擬機的依賴(在編寫程序時,不能依賴程序的及時終結來達到程序的正確性,因爲Java並不能確定程序時何時被GC垃圾回收堆回收的。還有不能依賴線程的優先級來達到程序的正確性,因爲線程調用的順序不能明確確定)
6.對用戶界面的依賴(下面三點個人覺得不用理解)
7.Java平臺實現的bug
8.測試

本星期最後一個總結在於Java的安全性是如何實現的?

Java提供了一個用戶可配置的“沙箱”,可以防止不可靠的Java程序。沙箱對不可靠程序的活動進行了限制,程序可以再沙箱的安全邊界內做任何事,但是不能進行任何跨越這些邊界的舉動。版本1.0中的沙箱限制:
1.對本地硬盤的讀寫操作
2.進行任何網絡連接,但不能連接到提供這個applet的源主機
3.創建新的進程
4.裝載新的動態連接庫

Java沙箱的基本組件是:
1.類裝載器結構
2.class文件檢查器
3.內置了Java虛擬機的安全特性
4.安全管理器及Java API

這裏我只對一、二兩點進行解釋,個人覺得三、四兩點太過於偏向底層,需要用到安全管理器、安全策略等等(至少我是看不懂,感覺幫助也不大)。

那麼類裝載器體系結構是如何防止惡意代碼去幹擾善意代碼的呢?
這是用過由不同的類裝載器裝入的類,提供不同的命名空間來實現的。

那麼類裝載器如何保護可信任的類庫?
在有雙親委派模式的情況下,如果網絡裝載器(個人理解也是系統裝載器)裝載的某段代碼發出指示,需要去下載一個和Java API相同名字的類,比如String類,只使用由他的雙親返回的類,如果沒有才能自己在下載。用這種方法,類裝載器的體系結構就可以防止他們用自己的版本替換Java中可信任的類了。在允許兩個類型之間對包內可見的成員進行訪問前,虛擬機不但要確定兩個類型屬於同一個包,並且還必須確認他們屬於同一個運行時包——它們必須是由同一個類裝載器裝載的。

class 文件檢查器是如何進行檢查掃描的?
1.第一趟:class文件結構的檢查:class文件確認他是否符合Java class文件的基本結構,並且確認class文件沒有被刪節,尾部沒有附帶其他字節。主要目的:保證這個字節序列正確地定義了一個新類型,它必須遵從Java class文件的固定格式。
2.第二趟:數據類型的語義檢查。檢查器查看每個組成部分,比如方法描述符(返回類型、參數的類型和個數、final有沒有被子類化)
3.第三趟:字節碼的驗證
4.第四趟:富豪引用的驗證(就是實例引用)

今天的總結就到這,如果發現我總結的不對,請批評指正交流,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章