Java是一門能夠跨平臺的語言,可是Java自己是不能夠實現跨平臺的,須要JVM實現跨平臺。javac編譯好後的class文件,在Windows、Linux、Mac等系統上,只要該系統安裝對應的Java虛擬機,class文件均可以運行。達到」一次編譯,處處運行」的效果。java
而JVM究竟是什麼呢?引用百度百科對JVM的介紹:算法
JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是經過在實際的計算機上仿真模擬各類計算機功能來實現的。編程
1.JVM主要包含類裝載器、運行時數據區(內存模型)、執行引擎。裏面內存模型有能夠細分包括本地方法棧、堆、棧(線程)、方法區(元空間)、程序計數器。如圖所示:數組
1.類裝載器的做用就是負責加載class文件,class文件在文件開頭有特定的文件標示,將class文件字節碼內容加載到內存中,並將這些內容轉換成方法區中的運行時數據結構而且ClassLoader只負責class文件的加載,至於它是否能夠運行,則由執行引擎(Execution Engine)決定。類加載器又有四大類加載器:緩存
啓動類加載器(Bootstrap ClassLoader):負責加載JRE核心類庫,像JRE中的rt.jar等(C/C++);數據結構
擴展類加載器(Extension ClassLoader):負責加載JRE擴展目錄ext中的jar包;多線程
系統類加載器(Application ClassLoader):負責加載ClassPath路徑下的類包;架構
自定義的類加載器(User ClassLoader):只加載指定目錄下的jar和class,想加載其它位置的類或jar時得自行定義類加載器;jvm
2.JVM中,對象都是在堆中分配內存空間的,棧只用於保存局部變量和臨時變量,若是是對象,只保存引用,實際內存仍是在堆中。棧的特色是先進後出,假設一個main方法,裏面執行了一個方法,咱們是後執行的那個方法即那個線程,可是執行完畢後,那個線程是先銷燬的。每一個方法在執行的同時都會建立一個棧幀,用於存儲局部變量表(存放局部變量的)、操做數棧(存放須要運算的數據)、動態連接、方法出口(執行完方法 回到main方法的位置)等信息,每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機中入棧到出棧的過程。即一個方法對應一塊棧幀內存區域(存放本方法的局部變量)。ui
3.方法區存儲已被虛擬機加載的類信息、常量(堆中的對象常量地址)、靜態變量、即時編譯器編譯後的代碼等數據。
4.本地方法棧和棧的做用相似,可是它服務的對象是native方法,該方法得由c語言來實現。
5.程序計數器做用是當CPU多線程切換的時候,切回到當前線程的時候,回到程序計數器計數的位置,繼續執行。
新生代包括Eden加上2個survivor區,執行minor gc以後,大多數的對象會被回收,活着的進入s0,再次minor gc,活着的對象eden+s0->s1,再次minor gc,eden+s1->s0…這裏虛擬機採起了分代收集的思想來管理內存,JVM給每一個對象一個對象年齡計數器,分代年齡達到15後即對象被執行了15次minor gc後移入老年代。除此以外,s區裝不下的大對象也會直接進入老年代。
最後,老年代存的就是一些大對象和須要連續內存空間的對象(靜態變量、緩存、線程池等),老年代滿了的話,會執行Full GC垃圾收集。官網對Full GC的解釋中介紹了個詞」Stop-The-World」,它會把全部的應用線程停掉,這時候系統會卡掉。JVM虛擬機調優的目標就是減小full gc即減小STW。
堆裏面存放new的對象和數組,Java優於其餘語言一個很重要的緣由就是它能自動處理垃圾對象,也就是有垃圾回收機制(GC)。有了垃圾回收機制有幾點好處編程簡單,系統不容易出錯。
1.什麼是垃圾?
咱們把沒有任何引用指向的對象或者一堆對象(循環引用)定義爲垃圾。
2.系統如何定位垃圾
3.常見的垃圾回收算法
複製算法它將可用內存按容量分爲大小相等的兩塊,每次只使用其中的一塊,當這一塊的內存用完了,就將還存活的對象複製到另一塊上面,而後再把已使用過的內存空間一次清理掉。
新生代收集器:Serial、ParNew、Parallel Scavenge
老年代收集器:CMS、Serial Old、Parallel Old
整堆收集器: G1
jdk1.8 默認垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)