1.0,jdk與jre和jvm的區別:
JDK(Java Development Kit):指的是Java開發工具集。JDK是整個Java的核心,包括了Java基礎類庫、Java運行環境(JRE)和Java開發工具。是做Java開發必須要安裝的。
JRE(Java Runtime Environment):指的是Java運行時環境。Java程序運行時必需要JRE的支持。如果系統只安裝JRE的話,則意味着系統可以跑任何Java程序,但不能做Java開發。
JVM (Java Virtual Machine):就是我們常說的java虛擬機,它是整個java實現跨平台的最核心的部分,所有的java程序首先被編譯為.class文件,這種類文件可以在虛擬機上運行,也就是說class並不直接與機器的操作系統相對應。而是經過虛擬機間接的與操作系統交互,由虛擬機將程序解釋給本地系統執行,只有jvm還不能將class執行,因為在解釋class的時候jvm需要調用解釋所需要的類庫lib,而jre包含lib類庫,jvm屏蔽了具體操作系統平台的相關信息,使得java程序只需要生成在java虛擬機上運行的目標代碼。可以在多種平台(操作系統)上不加修改的運行
如果你只是為了運行一下 Java 程序的話,那么你只需要安裝 JRE 就可以了。如果你需要進行一些 Java 編程方面的工作,那么你就需要安裝JDK了。但是,這不是絕對的。有時,即使您不打算在計算機上進行任何Java開發,仍然需要安裝JDK。例如,如果要使用JSP部署Web應用程序,那么從技術上講,您只是在應用程序服務器中運行Java程序。那你為什么需要JDK呢?因為應用程序服務器會將 JSP 轉換為 Java servlet,並且需要使用 JDK 來編譯 servlet。
1.1,Oracle JDK 和 OpenJDK 的對比
可能在看這個問題之前很多人和我一樣並沒有接觸和使用過 OpenJDK 。那么Oracle和OpenJDK之間是否存在重大差異?下面我通過收集到的一些資料,為你解答這個被很多人忽視的問題。
對於Java 7,沒什么關鍵的地方。OpenJDK項目主要基於Sun捐贈的HotSpot源代碼。此外,OpenJDK被選為Java 7的參考實現,由Oracle工程師維護。關於JVM,JDK,JRE和OpenJDK之間的區別,Oracle博客帖子在2012年有一個更詳細的答案:
問:OpenJDK存儲庫中的源代碼與用於構建Oracle JDK的代碼之間有什么區別?
答:非常接近 - 我們的Oracle JDK版本構建過程基於OpenJDK 7構建,只添加了幾個部分,例如部署代碼,其中包括Oracle的Java插件和Java WebStart的實現,以及一些封閉的源代碼派對組件,如圖形光柵化器,一些開源的第三方組件,如Rhino,以及一些零碎的東西,如附加文檔或第三方字體。展望未來,我們的目的是開源Oracle JDK的所有部分,除了我們考慮商業功能的部分。
總結:
- Oracle JDK大概每6個月發一次主要版本,而OpenJDK版本大概每三個月發布一次。但這不是固定的,我覺得了解這個沒啥用處。詳情參見:https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence。
- OpenJDK 是一個參考模型並且是完全開源的,而Oracle JDK是OpenJDK的一個實現,並不是完全開源的;
- Oracle JDK 比 OpenJDK 更穩定。OpenJDK和Oracle JDK的代碼幾乎相同,但Oracle JDK有更多的類和一些錯誤修復。因此,如果您想開發企業/商業軟件,我建議您選擇Oracle JDK,因為它經過了徹底的測試和穩定。某些情況下,有些人提到在使用OpenJDK 可能會遇到了許多應用程序崩潰的問題,但是,只需切換到Oracle JDK就可以解決問題;
- 在響應性和JVM性能方面,Oracle JDK與OpenJDK相比提供了更好的性能;
- Oracle JDK不會為即將發布的版本提供長期支持,用戶每次都必須通過更新到最新版本獲得支持來獲取最新版本;
- Oracle JDK根據二進制代碼許可協議獲得許可,而OpenJDK根據GPL v2許可獲得許可。
1.2,jvm作用詳解:
1.2.1,JVM作用:
Java虛擬機(JVM)是運行 Java 字節碼的虛擬機。JVM有針對不同系統的特定實現(Windows,Linux,macOS),目的是使用相同的字節碼,它們都會給出相同的結果。
1.2.2,什么是字節碼?采用字節碼的好處是什么?
在 Java 中,JVM可以理解的代碼就叫做字節碼(即擴展名為 .class 的文件),它不面向任何特定的處理器,只面向虛擬機。Java 語言通過字節碼的方式,在一定程度上解決了傳統解釋型語言執行效率低的問題,同時又保留了解釋型語言可移植的特點。所以 Java 程序運行時比較高效,而且,由於字節碼並不針對一種特定的機器,因此,Java程序無須重新編譯便可在多種不同操作系統的計算機上運行。
1.2.3,Java程序從源代碼到運行一般有下面3步:
我們需要格外注意的是 .class->機器碼 這一步。在這一步 JVM 類加載器首先加載字節碼文件,然后通過解釋器逐行解釋執行,這種方式的執行速度會相對比較慢。而且,有些方法和代碼塊是經常需要被調用的(也就是所謂的熱點代碼),所以后面引進了 JIT 編譯器,而JIT 屬於運行時編譯。當 JIT 編譯器完成第一次編譯后,其會將字節碼對應的機器碼保存下來,下次可以直接使用。而我們知道,機器碼的運行效率肯定是高於 Java 解釋器的。這也解釋了我們為什么經常會說 Java 是編譯與解釋共存的語言。
HotSpot采用了惰性評估(Lazy Evaluation)的做法,根據二八定律,消耗大部分系統資源的只有那一小部分的代碼(熱點代碼),而這也就是JIT所需要編譯的部分。JVM會根據代碼每次被執行的情況收集信息並相應地做出一些優化,因此執行的次數越多,它的速度就越快。JDK 9引入了一種新的編譯模式AOT(Ahead of Time Compilation),它是直接將字節碼編譯成機器碼,這樣就避免了JIT預熱等各方面的開銷。JDK支持分層編譯和AOT協作使用。但是 ,AOT 編譯器的編譯質量是肯定比不上 JIT 編譯器的。
總結:
Java虛擬機(JVM)是運行 Java 字節碼的虛擬機。JVM有針對不同系統的特定實現(Windows,Linux,macOS),目的是使用相同的字節碼,它們都會給出相同的結果。字節碼和不同系統的 JVM 實現是 Java 語言“一次編譯,隨處可以運行”的關鍵所在。
1.3,JVM的生命周期:
當啟動一個Java程序時,一個虛擬機實例也就誕生了。當該程序關閉退出,這個虛擬機實例也就隨之消亡。如果在同一台計算機上同時運行三個Java程序,將得到三個Java虛擬機實例。每個Java程序都運行於它自己的Java虛擬機實例中。
JVM實例對應了一個獨立運行的java程序,它是進程級別。
1,啟動。
啟動一個Java程序時,一個JVM實例就產生了,任何一個擁有publicstatic void main(String[] args)函數的class都可以作為JVM實例運行的起點
2,運行。
main()作為該程序初始線程的起點,任何其他線程均由該線程啟動。JVM內部有兩種線程:守護線程和非守護線程,main()屬於非守護線程,守護線程通常由JVM自己使用,java程序也可以標明自己創建的線程是守護線程
3,消亡。
當程序中的所有非守護線程都終止時,JVM才退出;若安全管理器允許,程序也可以使用Runtime類或者System.exit()來退出
1.4,JVM運行時數據區:
第一塊:PC寄存器
PC寄存器是用於存儲每個線程下一步將執行的JVM指令,如該方法為native的,則PC寄存器中不存儲任何信息。
第二塊:JVM棧
JVM棧是線程私有的,每個線程創建的同時都會創建JVM棧,JVM棧中存放的為當前線程中局部基本類型的變量(java中定義的八種基本類型:boolean、char、byte、short、int、long、float、double)、部分的返回結果以及Stack Frame,非基本類型的對象在JVM棧上僅存放一個指向堆上的地址
第三塊:堆(Heap)
它是JVM用來存儲對象實例以及數組值的區域,可以認為Java中所有通過new創建的對象的內存都在此分配,Heap中的對象的內存需要等待GC進行回收。
第四塊:方法區域(Method Area)
(1)在Sun JDK中這塊區域對應的為PermanetGeneration,又稱為持久代。
(2)方法區域存放了所加載的類的信息(名稱、修飾符等)、類中的靜態變量、類中定義為final類型的常量、類中的Field信息、類中的方法信息,當開發人員在程序中通過 Class對象中的getName、isInterface等方法來獲取信息時,這些數據都來源於方法區域,同時方法區域也是全局共享的,在一定的條件下它也會被GC,當方法區域需要使用的內存超過其允許的大小時,會拋出OutOfMemory的錯誤信息。
第五塊:運行時常量池(Runtime Constant Pool)
存放的為類中的固定的常量信息、方法和Field的引用信息等,其空間從方法區域中分配。
第六塊:本地方法堆棧(Native Method Stacks)
JVM采用本地方法堆棧來支持native方法的執行,此區域用於存儲每個native方法調用的狀態。