(8)jvm堆疊底層原理,伺服器啟動

weixin_34146805發表於2018-06-24

一、堆記憶體和棧記憶體

棧(stack)與堆(heap)都是Java用來在Ram中存放資料的地方。與C++不同,Java自動管理棧和堆,程式設計師不能直接地設定棧或堆。

棧:

簡單理解:堆疊(stack)是作業系統在建立某個程式或者執行緒(在支援多執行緒的作業系統中是執行緒)為這個執行緒建立的儲存區域,該區域具有先進後出的特性。

特點:存取速度比堆要,僅次於直接位於CPU中的暫存器。棧中的資料可以共享(意思是:棧中的資料可以被多個變數共同引用)。

缺點:存在棧中的資料大小與生存期必須是確定的,缺乏靈活性

相關存放物件:①一些基本型別的變數(,int, short, long, byte, float, double, boolean, char)和物件控制程式碼【例如:在函式中定義的一些基本型別的變數和物件的引用變數】。②方法的形參 直接在棧空間分配,當方法呼叫完成後從棧空間回收。

特殊:①方法的引用引數,在棧空間分配一個地址空間,並指向堆空間的物件區,當方法呼叫完成後從棧空間回收。②區域性變數new出來之後,在棧控制元件和堆空間中分配空間,當區域性變數生命週期結束後,它的棧空間立刻被回收,它的堆空間等待GC回收。

堆:

簡單理解:每個Java應用都唯一對應一個JVM例項,每一個JVM例項唯一對應一個堆。應用程式在執行中所建立的所有類例項或者陣列都放在這個堆中,並由應用所有的執行緒共享。Java中分配堆記憶體是自動初始化的,Java中所有物件的儲存控制元件都是在堆中分配的,但這些物件的引用則是在棧中分配,也就是一般在建立一個物件時,堆和棧都會分配記憶體。

特點:可以動態地分配記憶體大小、比較靈活,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的資料。在堆中分配的記憶體,由Java虛擬機器的自動垃圾回收器來管理。

缺點:由於要在執行時動態分配記憶體,存取速度較

主要存放:①由new建立的物件和陣列 ;②this

特殊:引用資料型別(需要用new來建立),既在棧控制元件分配一個地址空間,又在堆空間分配物件的類變數。

補充:在堆中產生了一個陣列或物件後,還可以在棧中定義一個特殊的變數,讓棧中這個變數的取值等於陣列或物件在堆記憶體中的首地址,棧中的這個變數就成了陣列或物件的引用變數。

引用變數就相當於是為陣列或物件起的一個名稱,以後就可以在程式中使用棧中的引用變數來訪問堆中的陣列或物件。

引用變數是普通變數,定義時在棧中分配記憶體,引用變數在程式執行到作用域外釋放。而陣列&物件本身在堆中分配,即使程式執行到使用new產生陣列和物件的語句所在地程式碼塊之外,陣列和物件本身佔用的堆記憶體也不會被釋放,陣列和物件在沒有引用變數指向它的時候,才變成垃圾,不能再被使用,但是仍然佔著記憶體,在隨後的一個不確定的時間被垃圾回收器釋放掉。這個也是java比較佔記憶體的主要原因

這裡可以理解為:String s1 = new String("abc");這裡面:"abc"表示棧中的一個儲存空間中的一個資料,new String("abc")表示存在於堆中的一個物件,這個物件的值為‘abc’,String s1則表示棧中定義的一個取了new String("abc")在堆中的首地址的一個特殊變數,也就是:s1成了引用變數,相當於一個別名。

二、 Tomcat原理簡析--伺服器啟動 

9930763-0003746d520cfb03.png

Tomcat啟動過程:

1.Boostrap類是tomcat啟動的入口,啟動tomcat實際上是呼叫了這個類的main方法:(1)新建一個Bootstrap例項並通過init方法來完成Catalina類的初始化,(2)對命令列引數進行理,預設執行start命令。start命令的處理主要通過三個方法來完成:setAwait(true), load(args), start()。這三個方法分別通過反射的方式來呼叫已經初始化的Catalina例項實際上整個啟動過程是由Catalina完成的。

2.Catalina的啟動過程

Catalina的啟動過程主要通過三個方法來完成:

(1)load方法完成對配置檔案解析server例項屬性設定

(2)然後通過start方法呼叫Server的start方法。Server被定義為一個介面,包含具體的服務管理方法。

(3)最後,通過Server的await方法來啟動一個監聽迴圈,當這個迴圈退出時stop方法才會被呼叫,從而停止伺服器

3.Server的啟動過程

Server介面定義了一系列的Service管理和伺服器生命週期管理方法,Server預設實現類是StandardServer, 這個類繼承自LifecycleBase,在init的時候呼叫了initInternal方法,start的時候呼叫startInternal方法,並且這兩個模板方法被StandardServer重寫

9930763-62010938ee5e122f.png

通過以上兩個呼叫就完成了所有Service的初始化和啟動,隨後通過await方法來使伺服器進入等待狀態:

通過一個while迴圈來建立ServerSocket監聽客戶端連線,同時會在該埠監聽客戶端的shutdown命令,主要配置是在conf/server.xml檔案中:

9930763-002565ccbceaba2e.png

通過設定這個埠為-1即可禁用網路命令停止tomcat服務。

Service的啟動過程

Service是開發者部署在tomcat上的web應用抽象概念,這個介面的預設實現是StandardService,也繼承自LifestyleBase類,相關的初始化和載入主要通過呼叫initInternal和startInternal來完成:

主要呼叫了container,executors和connectors的init和start來完成相關應用元件的載入,executors是在connector中管理的執行緒池,可以通過server.xml進行配置,預設是註釋的:

9930763-d0bbc04bd547affb.png

通過以上配置就完成了connector的線城池配置。整個啟動過程至此就完成了,主要包括init和start兩個階段,分別完成各個元件的初始化和啟動過程,如最上面圖

相關文章