更新時(shí)間:2020-02-26 09:49:14 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2666次
什么是Java虛擬機(jī)?為什么Java被稱作是“平臺(tái)無關(guān)的編程語言”?
Java虛擬機(jī)是一個(gè)可以執(zhí)行Java字節(jié)碼的虛擬機(jī)進(jìn)程。Java源文件被編譯成能被Java虛擬機(jī)執(zhí)行的字節(jié)碼文件。Java被設(shè)計(jì)成允許應(yīng)用程序可以運(yùn)行在任意的平臺(tái),而不需要程序員為每一個(gè)平臺(tái)單獨(dú)重寫或者是重新編譯。Java虛擬機(jī)讓這個(gè)變?yōu)榭赡埽驗(yàn)樗赖讓佑布脚_(tái)的指令長(zhǎng)度和其他特性。
Java內(nèi)存結(jié)構(gòu)?
方法區(qū)和對(duì)是所有線程共享的內(nèi)存區(qū)域;而java棧、本地方法棧和程序員計(jì)數(shù)器是運(yùn)行是線程私有的內(nèi)存區(qū)域。
Java堆(Heap),是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存。
方法區(qū)(MethodArea),方法區(qū)(MethodArea)與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
程序計(jì)數(shù)器(ProgramCounterRegister),程序計(jì)數(shù)器(ProgramCounterRegister)是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。
JVM棧(JVMStacks),與程序計(jì)數(shù)器一樣,Java虛擬機(jī)棧(JavaVirtualMachineStacks)也是線程私有的,它的生命周期與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候都會(huì)同時(shí)創(chuàng)建一個(gè)棧幀(StackFrame)用于存儲(chǔ)局部變量表、操作棧、動(dòng)態(tài)鏈接、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完成的過程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程。
本地方法棧(NativeMethodStacks),本地方法棧(NativeMethodStacks)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的,其區(qū)別不過是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。
解釋內(nèi)存中的棧(stack)、堆(heap)和方法區(qū)(methodarea)的用法
通常我們定義一個(gè)基本數(shù)據(jù)類型的變量,一個(gè)對(duì)象的引用,還有就是函數(shù)調(diào)用的現(xiàn)場(chǎng)保存都使用JVM中的棧空間;而通過new關(guān)鍵字和構(gòu)造器創(chuàng)建的對(duì)象則放在堆空間,堆是垃圾收集器管理的主要區(qū)域,由于現(xiàn)在的垃圾收集器都采用分代收集算法,所以堆空間還可以細(xì)分為新生代和老生代,再具體一點(diǎn)可以分為Eden、Survivor(又可分為FromSurvivor和ToSurvivor)、Tenured;方法區(qū)和堆都是各個(gè)線程共享的內(nèi)存區(qū)域,用于存儲(chǔ)已經(jīng)被JVM加載的類信息、常量、靜態(tài)變量、JIT編譯器編譯后的代碼等數(shù)據(jù);程序中的字面量(literal)如直接書寫的100、”hello”和常量都是放在常量池中,常量池是方法區(qū)的一部分,。棧空間操作起來最快但是棧很小,通常大量的對(duì)象都是放在堆空間,棧和堆的大小都可以通過JVM的啟動(dòng)參數(shù)來進(jìn)行調(diào)整,棧空間用光了會(huì)引發(fā)StackOverflowError,而堆和常量池空間不足則會(huì)引發(fā)OutOfMemoryError。
Stringstr=newString("hello");
上面的語句中變量str放在棧上,用new創(chuàng)建出來的字符串對(duì)象放在堆上,而”hello”這個(gè)字面量是放在方法區(qū)的。
補(bǔ)充1:較新版本的Java(從Java6的某個(gè)更新開始)中,由于JIT編譯器的發(fā)展和”逃逸分析”技術(shù)的逐漸成熟,棧上分配、標(biāo)量替換等優(yōu)化技術(shù)使得對(duì)象一定分配在堆上這件事情已經(jīng)變得不那么絕對(duì)了。
補(bǔ)充2:運(yùn)行時(shí)常量池相當(dāng)于Class文件常量池具有動(dòng)態(tài)性,Java語言并不要求常量一定只有編譯期間才能產(chǎn)生,運(yùn)行期間也可以將新的常量放入池中,String類的intern()方法就是這樣的。看看下面代碼的執(zhí)行結(jié)果是什么并且比較一下Java7以前和以后的運(yùn)行結(jié)果是否一致。
Strings1=newStringBuilder("go")
.append("od").toString();
System.out.println(s1.intern()==s1);
Strings2=newStringBuilder("ja")
.append("va").toString();
System.out.println(s2.intern()==s2);
對(duì)象分配規(guī)則
對(duì)象優(yōu)先分配在Eden區(qū),如果Eden區(qū)沒有足夠的空間時(shí),虛擬機(jī)執(zhí)行一次MinorGC。
大對(duì)象直接進(jìn)入老年代(大對(duì)象是指需要大量連續(xù)內(nèi)存空間的對(duì)象)。這樣做的目的是避免在Eden區(qū)和兩個(gè)Survivor區(qū)之間發(fā)生大量的內(nèi)存拷貝(新生代采用復(fù)制算法收集內(nèi)存)。
長(zhǎng)期存活的對(duì)象進(jìn)入老年代。虛擬機(jī)為每個(gè)對(duì)象定義了一個(gè)年齡計(jì)數(shù)器,如果對(duì)象經(jīng)過了1次MinorGC那么對(duì)象會(huì)進(jìn)入Survivor區(qū),之后每經(jīng)過一次MinorGC那么對(duì)象的年齡加1,知道達(dá)到閥值對(duì)象進(jìn)入老年區(qū)。
動(dòng)態(tài)判斷對(duì)象的年齡。如果Survivor區(qū)中相同年齡的所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對(duì)象可以直接進(jìn)入老年代。
空間分配擔(dān)保。每次進(jìn)行MinorGC時(shí),JVM會(huì)計(jì)算Survivor區(qū)移至老年區(qū)的對(duì)象的平均大小,如果這個(gè)值大于老年區(qū)的剩余值大小則進(jìn)行一次FullGC,如果小于檢查HandlePromotionFailure設(shè)置,如果true則只進(jìn)行MonitorGC,如果false則進(jìn)行FullGC。
什么是類的加載
類的加載指的是將類的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個(gè)java.lang.Class對(duì)象,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。類的加載的最終產(chǎn)品是位于堆區(qū)中的Class對(duì)象,Class對(duì)象封裝了類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu),并且向Java程序員提供了訪問方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)的接口。
以上就是動(dòng)力節(jié)點(diǎn)Java培訓(xùn)機(jī)構(gòu)小編介紹的“阿里Java工程師筆試題,Jvm必問面試題”的內(nèi)容,希望對(duì)大家有幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)