JAVA是一個面向對象的編程語言,由SUN公司的程序員所開發、它不只吸取了C++的各類優勢,並且還撇棄了C++中難以理解的概念,如多繼承、指針等;所以JAVA語言具備功能強大且簡單易用兩個特徵,JAVA做爲靜態面嚮對象語言的表明,是全世界最受歡迎的計算機語言(沒有之一)php
Java包含四個獨立卻又彼此相關的技術html
JVM,Java的虛擬機,在JVM上運行Java的bytecode(字節碼)前端
Java的程序編程語言java
Java Class,Java的類文件格式;其決定Java程序編譯出的字節碼應該遵循那些規範等程序員
JAVA的應用程序接口(Java API);爲了能讓Java的應用程序獲得更快更高效的開發,Java官方提供了Java APIweb
Java展現的文件一般都是Java類的文件格式,而Java的源程序要轉換成字節碼才能在JVM上運行算法
通常Java的程序代碼從寫到運行要通過如下幾個步驟:編程
Java程序語言+Java API 由程序員開發出源程序如X.java小程序
X.java源程序通過編譯器編譯爲Java的類文件如X.class(Java的類文件就是Java的字節碼)後端
在JVM中,class loader(類加載器)加載X.class類文件,而後由解釋器將X.calss文件由字節碼格式解釋成對應的OS平臺二進制程序,這樣Java程序就能夠再JVM上運行了
注:.class文件就是字節碼,但字節碼不能直接運行,仍需在JVM中由解釋器解釋成對應的OS二進制程序,才能運行(機器只能理解二進制)
下圖爲Java代碼從寫到執行的過程
JVM進行解釋的實現方式:
一次性解釋器,解釋字節碼並執行,但第二次執行須要從新解釋字節碼
即時編譯器,解釋完的類(字節碼)會緩存再內存中,讓下次執行時直接使用,不用再次執行,但這樣對全部解釋產生的二進制程序都緩存會很是佔用內存
自適應解釋器,只將執行頻率高的代碼進行解釋而後將解釋後的二進制程序進行緩存,下次執行無需解釋,通常只緩存20%的代碼解釋(認爲這20%的代碼完成了80%的操做)
下面是JAVA的執行過程
JVM(Java Virtual Machine)即Java虛擬機,是一種用於計算設備的規範,也是Java的核心和基礎,是Java解釋器和OS平臺之間的虛擬處理器,它是一種基於下層的操做系統和硬件平臺利用軟件方法抽象出的計算機。能夠在 上面執行Java的字節碼程序,正是由於JVM的存在Java才實現了一次編譯處處運行,可實現徹底跨平臺的運行
Java的編譯器只需面向JVM,生成JVM能理解的字節碼文件,而後由JVM將每一條指令翻譯成爲不一樣平臺的機器代碼(二進制程序),而後既能夠在對應的平臺執行
Java平臺由Java虛擬機(Java Virtual Machine,簡稱JVM)和Java 應用編程接口(Application Programming Interface,簡稱API)構成。Java應用編程接口爲此提供了一個獨立於操做系統的標準接口,可分爲基本部分和擴展部分。在硬件或操做系統平臺上安裝一個Java平臺以後,Java應用程序就可運行。Java平臺已經嵌入了幾乎全部的操做系統。這樣Java程序能夠只編譯一次,就能夠在各類系統中運行。Java應用編程接口已經從1.1x版發展到1.2版。經常使用的Java平臺基於Java1.5,最近版本爲Java7.0。
JRE (Java running Environment)Java的運行環境:JRE可讓編譯好的類(字節碼)運行起來,是讓Java運行起來的最小環境。簡單來講JRE=JVM+API(不包括與開發有關的API)
JDK (Java Development Kit)是Java語言的軟件開發工具包,是實現Java語言開發並讓其運行的最小環境。簡單來講JDK=Java語言+API+編譯器+JVM
依據Java應用領域的不一樣,JDK有如下幾種分類:
Java SE(J2SE),standard edition,標準版,是咱們一般用的一個版本,從JDK 5.0開始,更名爲Java SE。
Java EE(J2EE),enterprise edition,企業版,使用這種JDK開發J2EE應用程序,從JDK 5.0開始,更名爲Java EE。
Java ME(J2ME),micro edition,主要用於移動設備、嵌入式設備上的java應用程序,從JDK 5.0開始,更名爲Java ME。
沒有JDK的話,沒法編譯Java程序,若是想只運行Java程序,要確保已安裝相應的JRE。
下面來說Java兩個特殊的類Applet和Servlet
Applet是採用Java編程語言編寫的,通過編譯後Applet小程序能夠嵌入到HTML中去(含有Applet的網頁的HTML文件代碼中部帶有<applet> 和</applet>這樣一對標記),而後client端的瀏覽器中只要安裝JRE插件就能夠在client端運行這個Apple應用小程序,並將結果顯示在client上,這即是客戶端動態網站
可是客戶端動態網站有一很危險的地方,那就是若是有人給你往HTML網頁中嵌入的是一個有害的applet程序,你在client一執行會對你的電腦形成破壞,並且applet的執行必須在client端安裝有JRE,因此applet如今已經不多見了
HTML文件中關於Applet的信息至少應包含如下三點:
1)字節碼文件名(編譯後的Java文件,以.class爲後綴)
2)字節碼文件的地址
3)在網頁上顯示Applet的方式。
Servlet(Server Applplet)是用Java編寫的服務器端程序,其主要功能爲交互式的瀏覽和修改數據,生成動態的Web資源;Servlet可讓Java語言依據相似的CGI(common gateway interface)技術開發運行在服務器端的動態web資源,但在通訊量大的服務器上,Java Servlet 的優勢在於它們的執行速度更快於 CGI 程序。各個用戶請求被激活成單個程序中的一個線程,而無需建立單獨的進程,這意味着服務器端處理請求的系統開銷將明顯下降。
Servlet 的主要功能在於交互式地瀏覽和修改數據,生成動態 Web 內容。這個過程爲:
1.客戶端發送請求至服務器端;
2.服務器將請求信息發送至 Servlet;
3.Servlet 生成響應內容並將其傳給服務器。響應內容動態生成,一般取決於客戶端的請求;
4.服務器將響應返回給客戶端。
JSP(Java Server Page)Java的服務器頁面,它是Servlet的一個特殊的類,在根本上是一個簡化的Servlet設計,JSP是在傳統的網頁HTML文件(*.html或*.htm)中插入Java的程序段,從而造成了JSP文件(一般爲*.jsp);用JSP開發的web應用是支持跨平臺的,既能在Linux上運行,也能在其餘的操做系統上運行,開發JSP程序的一個著名框架是SSH(Structs、Spring、Hebernate)
JSP實現了Html語法中的java擴展(以 <%, %>形式)。JSP與Servlet同樣,是在服務器端執行的。一般返回給客戶端的就是一個HTML文本,所以客戶端只要有瀏覽器就能瀏覽(Applet要在client上裝JRE)。
注:
Applet只是將一個編譯後的Applet小程序嵌入到HTML中而後發送到client,在client端依據JRE運行;
Servlet主要是實現了用Java語言開發運行在server端的Web動態資源;而這些依據Java語言開發的web動態資源大多數都是.jsp資源
JSP是一種腳本語言,主要實現了將JAVA代碼嵌入到HTML中(這也是JSP和Servlet的最主要區別),從而生成了.jsp類的web動態資源,從而實現了基於Java技術的動態網站開發
JSP的運行性能要比PHP好,因此一些大型站點都用JSP開發,.jsp程序執行流程以下
.jsp由Jasper處理未.java源程序
.java由編譯器編譯爲.class
.class類在jvm上進行加載解釋並運行
JSP 的運程過程
一個JSP頁面有多個客戶訪問,下面是第一個客戶訪問JSP頁面時候,JSP頁面的執行流程:
客戶經過瀏覽器向服務器端的JSP頁面發送請求
JSP引擎檢查JSP文件對應的Servlet源代碼是否存在,若不存在轉向第4步,不然執行下一步
JSP引擎檢查JSP頁面是否須要修改,若沒修改,轉向第5步,不然執行下一步
JSP引擎將JSP頁面文件轉譯爲Servlet源代碼(相應的 .java 代碼)
JSP引擎將Servlet源代碼編譯爲相應字節碼( .class代碼 )
JSP引擎加載字節碼到內存
字節碼處理客戶請求,並將結果返回給客戶
在不修改JSP頁面的狀況下,除了第一個客戶訪問JSP頁面須要通過以上幾個步驟外,之後訪問該JSP頁面的客戶請求,直接發送給JSP對應的字節碼程序處理,並將處理結果返回給客戶,這種狀況下,JSP頁面既不須要啓動服務器,以便從新加載修改後的JSP頁面。
CGI(Common Gateway Interface)通用網關接口,CGI是外部應用程序(CGI程序)和Web服務器之間的接口標準(也能夠理解爲一種協議或機制),是在CGI程序和Web服務器之間傳遞信息的過程;CGI可讓一個客戶端,從網頁瀏覽器向執行在網絡服務器上的程序傳輸數據CGI描述了客戶端和服務器之間傳輸的一種標準
下面列子能夠理解CGI的做用
客戶端請求服務器,web服務器響應一個HTML靜態的表單,而用戶填寫完表單後又將此表單交給了web服務器(至關於又一次http請求),web服務器收到client端填寫的表單後會以CGI協議的方式提交給後端的應用程序讓其處理
不少應用程序均可以傳遞參數,CGI可讓用戶經過表單提供一些數據,而後把這些數據當作參數傳遞給相應的後端應用程序(如PHP)讓程序對其加工處理(不事後端應用程序是PHP、C、C++甚至是一個腳本CGI均可以與其交互)讓後端程序或腳原本處理數據,處理完後,後端程序再次經過CGI機制返回給前段的web服務器(httpd/Nginx)再由web服務器將結果封裝響應給客戶端
在LAMP和LNMP架構中PHP與前段Apache/Nginx之間就是經過CGI機制結合的,用於將客戶端的動態請求(主要爲php的動態資源請求)從前端web_server傳遞到後端的PHP,讓PHP處理。
Servlet Container(Servlet容器):包含JDK及JDK所不具有的功能,可讓一個Servlet運行起來,有相應的Servlet進程,Servlet進程負責接收前端CGI傳遞來的請求,並在本地的JVM上運行處理,而且負責監控本地的.java程序是否發生了修改,一旦發生修改則從新讓編譯器(由JDK提供)編譯成.class類
Web Container (Web容器)是一個包含Jasper和Servlet相關的技術的框架,其中Jasper負責監控本地的.jsp程序是否發生修改,一旦修改就根據需求將其裝換爲.java源代碼,而.java就交給Servlet處理
注:Web Container比Servlet Container多了一個Jasper
而如今不少的Web容器均可以直接和用戶的請求直接進行交互(即前端沒有web server解碼http請求和封裝http響應)web容器能夠徹底依靠本身的組件(對Tomcat來講爲web container的鏈接器)實現直接與client進行交互。可是讓鏈接器直接面對用戶的請求,可能會形成壓力過大處理不過來的狀況(若是鏈接器的性能不是很好),因此通常會在前端加一個web代理(如Nginx),讓Nginx創建、維持、釋放用戶的請求和鏈接,而當用戶的請求資源在前端web server(Nginx)上沒有緩存時,再由Nginx將請求轉發到後端web Container(如Tomcat)處理。而對應的這種架構叫:
Nginx + Java的Web Container(有時也成爲應用程序服務器)
但不管是Web Container仍是Servlet Container或者是JDK都是在JVM中運行的,Web Container|Servlet Container|JDK真正啓動後再OS中表現的都是一個JVM進程(JVM實例),即在JVM中若是你是一個Web Containter它就有Web Container的功能,是JDK就有JDK的功能,負責只有JVM自身的功能
JVM實例能夠在同一個JVM實例中啓動多個線程,從而完成併發響應,JVM中還包括:
線程私有內存區
程序計數器
Java虛擬機棧(主要用來保存本地變量)
線程共享內存區
方法區
堆(堆佔用的內存最大)主要用來存儲對象,當計數器爲0時就認爲對象已死,而後由GC(Garbage Collector)進行清除,避免堆溢出
而GC對對象的清理要依據必定的算法,有如下幾種
標記清除算法(哪一個對象死了先進行標記,而後統一清除),但這種機制有個弊端就是在GC進行垃圾清除時會讓CPU飆升,形成服務器性能突然降低,且會產生大量的內存碎片
複製算法,每一個對象存兩份,不會產生內存碎片可是內存使用率只有1/2
GC的種類
serial 一次只能回收一個對象,串行
parNew 一次能夠回收讀個,並行回收
CMS(Concurrent Mark Sweet)並行標記清除,多線程,儘量下降清除對JVM中程序的停頓,但缺點是沒法收集浮動垃圾(只要線程在運行,就不能收集)
G 1 特色是不會產生內存碎片、能夠定義停頓的時間
祝你們新年快樂!!!2017 努力!奮鬥!!!