JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫(xiě),JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。引入Java語(yǔ)言虛擬機(jī)后,Java語(yǔ)言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯。
在成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶,提高在線咨詢(xún)和轉(zhuǎn)化,使成都網(wǎng)站營(yíng)銷(xiāo)成為有效果、有回報(bào)的無(wú)錫營(yíng)銷(xiāo)推廣。創(chuàng)新互聯(lián)專(zhuān)業(yè)成都網(wǎng)站建設(shè)十載了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。
Java語(yǔ)言使用Java虛擬機(jī)屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語(yǔ)言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。下面, 陜西優(yōu)就業(yè)小編給大家分享十道題,大家可以嘗試著回答一下以下問(wèn)題:
qunhao: 838 940 752
一、內(nèi)存模型以及分區(qū),需要詳細(xì)到每個(gè)區(qū)放什么。
(1)JVM 分為堆區(qū)和棧區(qū),還有方法區(qū),初始化的對(duì)象放在堆里面,引用放在棧里面, class 類(lèi)信息常量池(static 常量和 static 變量)等放在方法區(qū) new:
(2)方法區(qū):主要是存儲(chǔ)類(lèi)信息,常量池(static 常量和 static 變量),編譯后的代碼(字 節(jié)碼)等數(shù)據(jù) · 堆:初始化的對(duì)象,成員變量(那種非 static 的變量),所有的對(duì)象實(shí)例和數(shù)組都要 在堆上分配
(3)棧:棧的結(jié)構(gòu)是棧幀組成的,調(diào)用一個(gè)方法就壓入一幀,幀上面存儲(chǔ)局部變量表,操 作數(shù)棧,方法出口等信息,局部變量表存放的是 8 大基礎(chǔ)類(lèi)型加上一個(gè)應(yīng)用類(lèi)型,所 以還是一個(gè)指向地址的指針
(4)本地方法棧:主要為 Native 方法服務(wù)
(5)程序計(jì)數(shù)器:記錄當(dāng)前線程執(zhí)行的行號(hào)
二、簡(jiǎn)述java垃圾回收機(jī)制?
在java中,程序員是不需要顯示的去釋放一個(gè)對(duì)象的內(nèi)存的,而是由虛擬機(jī)自行執(zhí)行。在JVM中,有一個(gè)垃圾回收線程,它是低優(yōu)先級(jí)的,在正常情況下是不會(huì)執(zhí)行的。
只有在虛擬機(jī)空閑或者當(dāng)前堆內(nèi)存不足時(shí),才會(huì)觸發(fā)執(zhí)行,掃面那些沒(méi)有被任何引用的對(duì)象,并將它們添加到要回收的集合中,進(jìn)行回收。
三、什么是類(lèi)加載器,類(lèi)加載器有哪些?
實(shí)現(xiàn)通過(guò)類(lèi)的權(quán)限定名獲取該類(lèi)的二進(jìn)制字節(jié)流的代碼塊叫做類(lèi)加載器。
主要有一下四種類(lèi)加載器:
(1)啟動(dòng)類(lèi)加載器(Bootstrap ClassLoader)用來(lái)加載java核心類(lèi)庫(kù),無(wú)法被java程序直接引用。
(2)擴(kuò)展類(lèi)加載器(extensions class loader):它用來(lái)加載 Java 的擴(kuò)展庫(kù)。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類(lèi)加載器在此目錄里面查找并加載 Java 類(lèi)。
(3)系統(tǒng)類(lèi)加載器(system class loader):它根據(jù) Java 應(yīng)用的類(lèi)路徑(CLASSPATH)來(lái)加載 Java 類(lèi)。一般來(lái)說(shuō),Java 應(yīng)用的類(lèi)都是由它來(lái)完成加載的??梢酝ㄟ^(guò)ClassLoader.getSystemClassLoader()來(lái)獲取它。
(4)用戶自定義類(lèi)加載器,通過(guò)繼承 java.lang.ClassLoader類(lèi)的方式實(shí)現(xiàn)。
四、GC 的兩種判定方法
(1)引用計(jì)數(shù)法:指的是如果某個(gè)地方引用了這個(gè)對(duì)象就+1,如果失效了就-1,當(dāng)為 0 就會(huì)回收但是 JVM 沒(méi)有用這種方式,因?yàn)闊o(wú)法判定相互循環(huán)引用(A 引用 B,B 引用 A) 的情況。
(2)引用鏈法: 通過(guò)一種 GC ROOT 的對(duì)象(方法區(qū)中靜態(tài)變量引用的對(duì)象等-static 變量)來(lái)判斷,如果有一條鏈能夠到達(dá) GC ROOT 就說(shuō)明,不能到達(dá)GC ROOT 就說(shuō)明可以回收 。
五、GC 收集器有哪些?CMS 收集器與 G1 收集器的特點(diǎn)。
并行收集器:串行收集器使用一個(gè)單獨(dú)的線程進(jìn)行收集,GC 時(shí)服務(wù)有停頓時(shí)間 串行收集器:次要回收中使用多線程來(lái)執(zhí)行 CMS 收集器是基于“標(biāo)記—清除”算法實(shí)現(xiàn)的,經(jīng)過(guò)多次標(biāo)記才會(huì)被清除 G1 從整體來(lái)看是基于“標(biāo)記—整理”算法實(shí)現(xiàn)的收集器,從局部(兩個(gè) Region 之間) 上來(lái)看是基于“復(fù)制”算法實(shí)現(xiàn)的 。
六、說(shuō)一下堆棧的區(qū)別?
(1)功能方面:堆是用來(lái)存放對(duì)象的,棧是用來(lái)執(zhí)行程序的。
(2)共享性:堆是線程共享的,棧是線程私有的。
(3)空間大?。憾汛笮∵h(yuǎn)遠(yuǎn)大于棧。
七、說(shuō)一下類(lèi)裝載的執(zhí)行過(guò)程?
類(lèi)裝載分為以下 5 個(gè)步驟:
(1)加載:根據(jù)查找路徑找到相應(yīng)的 class 文件然后導(dǎo)入;
(2)檢查:檢查加載的 class 文件的正確性;
(3)準(zhǔn)備:給類(lèi)中的靜態(tài)變量分配內(nèi)存空間;
(4)解析:虛擬機(jī)將常量池中的符號(hào)引用替換成直接引用的過(guò)程。符號(hào)引用就理解為一個(gè)標(biāo)示,而在直接引用直接指向內(nèi)存中的地址;
(5)初始化:對(duì)靜態(tài)變量和靜態(tài)代碼塊執(zhí)行初始化工作。
八、簡(jiǎn)述minor gc和full gc
(1)Minor GC:從新生代回收內(nèi)存,關(guān)鍵是Eden區(qū)內(nèi)存不足,造成不足的原因是Java對(duì)象大部分是朝生夕死(java局部對(duì)象),而死掉的對(duì)象就需要在合適的時(shí)機(jī)被JVM回收.
(2)Major GC:從老年代回收內(nèi)存,一般比Minor GC慢10倍以上。
(3)Full GC:對(duì)整個(gè)堆來(lái)說(shuō)的,出現(xiàn)Full GC通常伴隨至少一次Minor GC,但非絕對(duì)。Full GC被觸發(fā)的時(shí)候:老年代內(nèi)存不足;持久代內(nèi)存不足;統(tǒng)計(jì)得到的Minor GC晉升到老年代平均大小大于老年代空間。
九、Java內(nèi)存模型的happen before原則
如果兩個(gè)操作存在happens-before關(guān)系,那么前一個(gè)操作的結(jié)果就會(huì)對(duì)后面一個(gè)操作可見(jiàn),是定義的兩個(gè)操作之間的偏序關(guān)系,常見(jiàn)的規(guī)則:
(1)程序順序規(guī)則:一個(gè)線程中每個(gè)操作,happens-before于該線程中的任意后續(xù)操作。
(2)監(jiān)視器鎖規(guī)則:對(duì)一個(gè)鎖的解鎖,happens-before于隨后這個(gè)鎖的加鎖。
(3)volatile變量規(guī)則:對(duì)一個(gè)volatile域的寫(xiě),happens-before于任意后續(xù)對(duì)這個(gè)域的讀。
(4)傳遞性:若A happens-before B,B happens-before C,則A happens-before C.
(5)start()規(guī)則:如果線程A執(zhí)行ThreadB.start(),那么A線程的ThreadB.start()操作happens-before于線程B中的任意操作。
(6)join()規(guī)則:若線程A 執(zhí)行ThreadB.join()并成功返回,則線程B的任意操作happens-before于線程A從ThreadB.jion()操作返回成功。
十、說(shuō)一下 JVM 有哪些垃圾回收算法?
(1)標(biāo)記-清除算法:標(biāo)記無(wú)用對(duì)象,然后進(jìn)行清除回收。缺點(diǎn):效率不高,無(wú)法清除垃圾碎片。
(2)標(biāo)記-整理算法:標(biāo)記無(wú)用對(duì)象,讓所有存活的對(duì)象都向一端移動(dòng),然后直接清除掉端邊界以外的內(nèi)存。
(3)復(fù)制算法:按照容量劃分二個(gè)大小相等的內(nèi)存區(qū)域,當(dāng)一塊用完的時(shí)候?qū)⒒钪膶?duì)象復(fù)制到另一塊上,然后再把已使用的內(nèi)存空間一次清理掉。缺點(diǎn):內(nèi)存使用率不高,只有原來(lái)的一半。
(4)分代算法:根據(jù)對(duì)象存活周期的不同將內(nèi)存劃分為幾塊,一般是新生代和老年代,新生代基本采用復(fù)制算法,老年代采用標(biāo)記整理算法。