1.2019年周陽老師JVM·第一部分

JVM架構圖

常見的虛擬機面試題:主要是考淘寶的大神周志明寫的那本書
在這裏插入圖片描述

JVM體系結構概述

在這裏插入圖片描述
擴展:JNI–java調用底層硬件,android還在用。
在這裏插入圖片描述
對於這張圖,做一個知識鏈接,runtimeException是從運行時數據區拋出來的。

類裝載器

在這裏插入圖片描述
方法區:放類的描述信息,就是放模板的地方。
classLoader有多種(粗說三個,細說四個,下面介紹)。類裝載器之前是class(小寫),裝載之後是Class。也就是下面這個類。
在這裏插入圖片描述
特定的文件標示是java的圖標:cafe babe
在這裏插入圖片描述

類加載器都有哪些?

在這裏插入圖片描述
在這裏插入圖片描述
系統自帶的類,比如object,打印類加載器是null,實際上自帶的類是被bootstrap classload加載的,但是你打印不出來。bootstrapclassloader是頂級的類加載器,不再有父類了。所有你一安裝jdk就能用的,都是由bootstapclassloader加載。是安裝路徑lib目錄下的rt.jar,也就是runtime.jar,運行時需要的jar包。可以打開rt.jar看一下,如下:
在這裏插入圖片描述
在這裏插入圖片描述
如果是自己編寫的類,走的是appclassloader這個加載器。
擴展類加載器extentionclassloader,加載的是javax開頭的包:
在這裏插入圖片描述
在這裏插入圖片描述
怎麼理解呢?rt.jar中裝載的是基礎功能,ext文件夾下的jar包是擴展功能(如上圖)。

在這裏插入圖片描述
在這裏插入圖片描述
剛纔appclassloader前面有個類前綴(上2圖),這個類是jvm相關調用的入口程序。
可以根據類加載器的繼承關係,打印出下圖中的內容。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
根據這個實驗我們可以看出類加載器是有繼承關係的。
可以關注的是classloader是一個抽象類,必須被繼承,如下:
在這裏插入圖片描述
就是通過這個抽象類來自定義類加載器。

雙親委派機制

類加載的考點:有哪幾種類加載器?什麼是classloader類加載器的雙親委派機制?沙箱安全機制?
雙親委派機制:我爸是李剛,有事找我爹!根據類加載器的繼承結構,找一個類先從爺爺輩類加載器(bootstrapclassloader)往下找,一直找到孫子輩。也就是下圖:
在這裏插入圖片描述
找到最下方找不到就會報錯:class not found exception。
如果出現包名+類名與java自帶的重合,如下圖,會發生什麼事呢?
在這裏插入圖片描述
結果是會運行失敗:
在這裏插入圖片描述
個人理解:就因爲雙親委派機制,在bootstrapclassloader類加載器這一層,就找到了String這個類,並進行了加載,但是jdk自帶的String類,並沒有main函數,所以出現了上圖的報錯。雙親委派機制就是往上捅

也就是爲了用戶寫的代碼,不污染原廠自帶的代碼,提供了雙親委派機制來保證沙箱安全。保證大家使用不同的類加載器加載的String都是同一個。先找到,先使用,後面的不考慮。
在這裏插入圖片描述
執行引擎沒啥好說,加載完了就執行就ok了。
在這裏插入圖片描述

本地接口

在這裏插入圖片描述
在這裏插入圖片描述
我們平時所說的堆棧,指的是java棧(new出來的對象的引用放於此),而不是本地方法棧。
以線程Thread的start類引入:java的多線程是跟操作系統有關係(進程和線程是操作系統的概念)。
在這裏插入圖片描述
實際上底層是調用的start0這個方法。
這裏補充一下線程的6種狀態:
Java中的線程的狀態分爲6種。

  • 初始(NEW):新創建了一個線程對象,但還沒有調用start()方法。
  • 運行(RUNNABLE):Java線程中將就緒(ready)和運行中(running)兩種狀態籠統的成爲“運行”。
    線程對象創建後,其他線程(比如main線程)調用了該對象的start()方法。該狀態的線程位於可運行線程池中,等待被線程調度選中,獲取cpu 的使用權,此時處於就緒狀態(ready)。就緒狀態的線程在獲得cpu 時間片後變爲運行中狀態(running)。
  • 阻塞(BLOCKED):表線程阻塞於鎖。
  • 等待(WAITING):進入該狀態的線程需要等待其他線程做出一些特定動作(通知或中斷)。
  • 超時等待(TIME_WAITING):該狀態不同於WAITING,它可以在指定的時間內自行返回。
  • 終止(TERMINATED):表示該線程已經執行完畢。
    知識鏈接:http://www.zhiliaotang.net/jishujiaoliu/java/249.html
    如果一個線程啓動2次,則會報錯。如下:
    在這裏插入圖片描述
    因爲源碼裏面線程的狀態不對,在啓動的時候就會拋出異常:
    在這裏插入圖片描述
    關注一下start0方法:native修飾,只有方法聲明,沒有方法的實現。
    在這裏插入圖片描述
    用native修飾的方法,調用的事操作系統的函數或者c語言函數庫的功能,不是java本身的功能。
    如果是native方法就放在native棧(native方法專用)裏面,因爲他不是java具體實現的方法,不應該放在方法棧。
    在這裏插入圖片描述
    native方法的具體實現交給了底層的第三方函數庫。這是早期java調用c留的一種接口。
    總結:
    在這裏插入圖片描述

pc寄存器

在這裏插入圖片描述
register:寄存器,CPU裏的一小塊空間。
pc寄存器就是一個指針,指着這個方法運行完了之後,下一個方法是誰。
在這裏插入圖片描述
pc寄存器:線程私有,內存佔用很少,幾乎不存在垃圾回收。

小總結

在這裏插入圖片描述
爲什麼要有雙親委派機制:因爲要沙箱安全,保證調用的基礎的類都是同一個。保護原生類,防止被污染。

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章