Java的前世此生php
Java之父詹姆斯·高斯林:html
1967年, 12歲用報廢的電話機和電視作了一臺電子遊戲機;java
1983年, 得到卡內基梅隆大學計算機科學博士學位;程序員
1983年, 畢業後設計了IBM第一代工做站;編程
1990年, 領導開發Sun用於數字家電的編程語言Oak(橡樹);數組
1994年, Oak被改名爲Java, 在硅谷發佈並引起熱潮;tomcat
2000年, Java成爲世界上最流行的編程語言安全
JDK(Java Development Kit)oracle
JDK是Java開發工具包,是Sun Microsystems針對Java開發員的產品。app
JDK中包含JRE,在JDK的安裝目錄下有一個名爲jre的目錄,裏面有兩個文件夾bin和lib,在這裏能夠認爲bin裏的就是jvm,lib中則是jvm工做所須要的類庫,而jvm和 lib和起來就稱爲jre。
JDK是整個JAVA的核心,包括了Java運行環境JRE(Java Runtime Envirnment)、一堆Java工具(javac/java/jdb等)和Java基礎的類庫(即Java API 包括rt.jar)。
①SE(J2SE),standard edition,標準版,是咱們一般用的一個版本,從JDK 5.0開始,更名爲Java SE。
②EE(J2EE),enterprise edition,企業版,使用這種JDK開發J2EE應用程序,從JDK 5.0開始,更名爲Java EE。
③ME(J2ME),micro edition,主要用於移動設備、嵌入式設備上的java應用程序,從JDK 5.0開始,更名爲Java ME。
金字塔結構 JDK=JRE+JVM+其它 運行Java程序通常都要求用戶的電腦安裝JRE環境(Java Runtime Environment);沒有jre,java程序沒法運行;而沒有java程序,jre就沒有用武之地。
Java原理圖以下
注意:java的關鍵字和標識符是不可更改的
boolean 只有兩個值:true、false,可使用 1 bit 來存儲,可是具體大小沒有明確規定。JVM 會在編譯時期將 boolean 類型的數據轉換爲 int,使用 1 來表示 true,0 表示 false。JVM 支持 boolean 數組,可是是經過讀寫 byte 數組來實現的。
JVM就是一臺虛擬的機器, Java程序編譯成字節碼就能在全部JVM上運行. JVM能夠說是整個Java生態系統的心臟, 它提供了兩大核心優點:
強的跨平臺性: 除Windows和OS X以外, 還支持所有的Linux發行版和Solaris等較小 衆的操做系統
超強的運行效率: JVM在編譯和運行時會對程序作大量優化, 提升程序運行效率
因爲JVM顯著的技術優點, 除Java外, 還有一系列現代編程語言是基於 JVM技術的, 這極大地擴展了Java程序員將來的發展空間
Java虛擬機的體系結構
·每一個JVM都有兩種機制:
①類裝載子系統:裝載具備適合名稱的類或接口
②執行引擎:負責執行包含在已裝載的類或接口中的指令
·每一個JVM都包含:
方法區、Java堆、Java棧、本地方法棧、指令計數器及其餘隱含寄存器
對於JVM的學習,在我看來這麼幾個部分最重要:
Java代碼編譯和執行的整個過程
JVM內存管理及垃圾回收機制
下面分別對這幾部分進行說明:
二、Java代碼編譯和執行的整個過程
也正如前面所說,Java代碼的編譯和執行的整個過程大概是:開發人員編寫Java代碼(.java文件),而後將之編譯成字節碼(.class文件),再而後字節碼被裝入內存,一旦字節碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。
(1)Java代碼編譯是由Java源碼編譯器來完成,也就是Java代碼到JVM字節碼(.class文件)的過程。 流程圖以下所示:
(2)Java字節碼的執行是由JVM執行引擎來完成,流程圖以下所示:
Java代碼編譯和執行的整個過程包含了如下三個重要的機制:
·Java源碼編譯機制
·類加載機制
·類執行機制
(1)Java源碼編譯機制
Java 源碼編譯由如下三個過程組成:
①分析和輸入到符號表
②註解處理
③語義分析和生成class文件
流程圖以下所示:
最後生成的class文件由如下部分組成:
①結構信息:包括class文件格式版本號及各部分的數量與大小的信息
②元數據:對應於Java源碼中聲明與常量的信息。包含類/繼承的超類/實現的接口的聲明信息、域與方法聲明信息和常量池
③方法信息:對應Java源碼中語句和表達式對應的信息。包含字節碼、異常處理器表、求值棧與局部變量區大小、求值棧的類型記錄、調試符號信息
(2)類加載機制
JVM的類加載是經過ClassLoader及其子類來完成的,類的層次關係和加載順序能夠由下圖來描述:
①Bootstrap ClassLoader
負責加載$JAVA_HOME中jre/lib/rt.jar裏全部的class,由C++實現,不是ClassLoader子類
②Extension ClassLoader
負責加載java平臺中擴展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目錄下的jar包
③App ClassLoader
負責記載classpath中指定的jar包及目錄中class
④Custom ClassLoader
屬於應用程序根據自身須要自定義的ClassLoader,如tomcat、jboss都會根據j2ee規範自行實現ClassLoader
加載過程當中會先檢查類是否被已加載,檢查順序是自底向上,從Custom ClassLoader到BootStrap ClassLoader逐層檢查,只要某個classloader已加載就視爲已加載此類,保證此類只全部ClassLoader加載一次。而加載的順序是自頂向下,也就是由上層來逐層嘗試加載此類。
(3)類執行機制
JVM是基於堆棧的虛擬機。JVM爲每一個新建立的線程都分配一個堆棧.也就是說,對於一個Java程序來講,它的運行就是經過對堆棧的操做來完成的。堆棧以幀爲單位保存線程的狀態。JVM對堆棧只進行兩種操做:以幀爲單位的壓棧和出棧操做。
JVM執行class字節碼,線程建立後,都會產生程序計數器(PC)和棧(Stack),程序計數器存放下一條要執行的指令在方法內的偏移量,棧中存放一個個棧幀,每一個棧幀對應着每一個方法的每次調用,而棧幀又是有局部變量區和操做數棧兩部分組成,局部變量區用於存放方法中的局部變量和參數,操做數棧中用於存放方法執行過程當中產生的中間結果。棧的結構以下圖所示:
JRE(Java Runtime Enviroment)是Java的運行環境。面向Java程序的使用者,而不是開發者。若是你僅下載並安裝了JRE,那麼你的系統只能運行Java程序。JRE是運行Java程序所必須環境的集合,包含JVM標準實現及 Java核心類庫。它包括Java虛擬機、Java平臺核心類和支持文件。它不包含開發工具(編譯器、調試器等)。
JDK(Java Development Kit)又稱J2SDK(Java2 Software Development Kit),是Java開發工具包,它提供了Java的開發環境(提供了編譯器javac等工具,用於將java文件編譯爲class文件)和運行環境(提 供了JVM和Runtime輔助包,用於解析class文件使其獲得運行)。若是你下載並安裝了JDK,那麼你不只能夠開發Java程序,也同時擁有了運 行Java程序的平臺。JDK是整個Java的核心,包括了Java運行環境(JRE),一堆Java工具tools.jar和Java標準類庫 (rt.jar)。
2. 區別
JRE主要包含:java類庫的class文件(都在lib目錄下打包成了jar)和虛擬機(jvm.dll);JDK主要包含:java類庫的 class文件(都在lib目錄下打包成了jar)並自帶一個JRE。那麼爲何JDK要自帶一個JRE呢?並且jdk/jre/bin下的client 和server兩個文件夾下都包含jvm.dll(說明JDK自帶的JRE有兩個虛擬機)。
記得在環境變量path中設置jdk/bin路徑麼?老師會告訴你們不設置的話javac和java是用不了的。確實jdk/bin目錄下包含了全部的命令。但是有沒有人想過咱們用的java命令並非jdk/bin目錄下的而是jre/bin目錄下的呢?不信能夠作一個實驗,你們能夠把jdk /bin目錄下的java.exe剪切到別的地方再運行java程序,發現了什麼?一切OK!(JRE中沒有javac命令,緣由很簡單,它不是開發環境)那麼有人會問了?我明明沒有設置jre/bin目錄到環境變量中啊?試想一下若是java爲了提供給大多數人使用,他們是不須要jdk作開發的,只需 要jre能讓java程序跑起來就能夠了,那麼每一個客戶還須要手動去設置環境變量多麻煩啊?因此安裝jre的時候安裝程序自動幫你把jre的 java.exe添加到了系統變量中,驗證的方法很簡單,去Windows/system32下面去看看吧,發現了什麼?有一個java.exe。
3. 難點
若是安裝了JDK,你的電腦就有兩套JRE(JRE自己和JDK中的JRE),前面這套比後面那套少了Server端的Java虛擬機。
(1)爲何Sun要讓JDK安裝兩套相同的JRE?這是由於JDK裏面有不少用Java所編寫的開發工具(如javac.exe、jar.exe 等),並且都放置在/lib/tools.jar裏。若是咱們將tools.jar更名爲tools1.jar,而後運行javac.exe,顯示以下結 果:Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac/Main。這個意思是說,你輸入javac.exe與輸入java -cp c:/jdk/lib/tools.jar com.sun.tools.javac.Main 是同樣的,會獲得相同的結果。從這裏咱們能夠證實javac.exe只是一個包裝器(Wrapper),而製做的目的是爲了讓開發者免於輸入太長的指命。 並且能夠發現/lib目錄下的程序都很小,不大於29K,從這裏咱們能夠得出一個結論。就是JDK裏的工具幾乎是用Java所編寫,因此也是Java應用 程序,所以要使用JDK所附的工具來開發Java程序,也必需要自行附一套JRE才行,因此位於JDK目錄下的那套JRE就是用來運行通常Java程序 的。
(2)若是一臺電腦安裝兩套以上的JRE,誰來決定呢?這個重大任務就落在java.exe身上。java.exe的工做就是找到合適的JRE來運 行Java程序。java.exe依照如下的順序來查找JRE:1)本身的目錄下有沒有JRE;2)父目錄有沒有JRE;3)查詢註冊表: [HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Runtime Environment]。因此java.exe的運行結果與你的電腦裏面哪一個JRE被執行有很大的關係。
(3)JDK-->JRE-->Bin目錄下有兩個文件夾:server與client,這是真正的jvm.dll所在。 jvm.dll沒法單獨工做,當jvm.dll啓動後,會使用explicit的方法(就是使用Win32 API之中的LoadLibrary()與GetProcAddress()來載入輔助用的動態連接庫),而這些輔助用的動態連接庫(.dll)都必須位 於jvm.dll所在目錄的父目錄之中。所以想使用哪一個JVM,只須要設置PATH,指向JRE所在目錄下的jvm.dll。
4. 最主流的JDK是Sun公司發佈的JDK,除了Sun以外,還有不少公司和組織都開發了本身的JDK,例如IBM公司開發的JDK,BEA公司的Jrocket,還有GNU組織開發的JDK等等。
普及:Java 與 C++ 的區別
What are the main differences between Java and C++?