詳情描述
在互聯(lián)網(wǎng)市場上,java程序員的崗位可謂是門庭若市,人才濟(jì)濟(jì),如何擠到一個合適自己的崗位,拉勾IT課java小編針對這一點,進(jìn)行了jvm的介紹。
1.Java的內(nèi)存劃分?
程序計數(shù)器(PC,ProgramCounterRegister)。在JVM規(guī)范中,每個線程都有它自己的程序計數(shù)器,并且任何時間一個線程都只有一個方法在執(zhí)行,也就是所謂的當(dāng)前方法。程序計數(shù)器會存儲當(dāng)前線程正在執(zhí)行的Java方法的JVM指令地址;或者,如果是在執(zhí)行本地方法,則是未指定值(undefined)。( 不會拋出
第二,Java虛擬機棧(JavaVirtualMachineStack),早期也叫Java棧。每個線程在創(chuàng)建時都會創(chuàng)建一個虛擬機棧,其內(nèi)部保存一個個的棧幀(StackFrame),對應(yīng)著一次次的Java方法調(diào)用。
前面談程序計數(shù)器時,提到了當(dāng)前方法;同理,在一個時間點,對應(yīng)的只會有一個活動的棧幀,通常叫作當(dāng)前幀,方法所在的類叫作當(dāng)前類。如果在該方法中調(diào)用了其他方法,對應(yīng)的新的棧幀會被創(chuàng)建出來,成為新的當(dāng)前幀,一直到它返回結(jié)果或者執(zhí)行結(jié)束。JVM直接對Java棧的操作只有兩個,就是對棧幀的壓棧和出棧。
棧幀中存儲著局部變量表、操作數(shù)(operand)棧、動態(tài)鏈接、方法正常退出或者異常退出的定義等。
第三,堆(Heap),它是Java內(nèi)存管理的核心區(qū)域,用來放置Java對象實例,幾乎所有創(chuàng)建的Java對象實例都是被直接分配在堆上。堆被所有的線程共享,在虛擬機啟動時,我們指定的“Xmx”之類參數(shù)就是用來指定較大堆空間等指標(biāo)。
(編譯器通過逃逸分析,確定對象是在棧上分配還是在堆上分配)
理所當(dāng)然,堆也是垃圾收集器重點照顧的區(qū)域,所以堆內(nèi)空間還會被不同的垃圾收集器進(jìn)行進(jìn)一步的細(xì)分,較有名的就是新生代、老年代的劃分。
第四,方法區(qū)這也是所有線程共享的一塊內(nèi)存區(qū)域,用于存儲所謂的元(Meta)數(shù)據(jù),例如類結(jié)構(gòu)信息,以及對應(yīng)的運行時常量池、字段、方法代碼等。
由于早期的實現(xiàn),很多人習(xí)慣于將方法區(qū)稱為永久代(PermanentGeneration)。OracleJDK8中將永久代移除,同時增加了元數(shù)據(jù)區(qū)(Metaspace)。
第五,運行時常量池(Run-TimeConstantPool),這是方法區(qū)的一部分。如果仔細(xì)分析過反編譯的類文件結(jié)構(gòu),你能看到版本號、字段、方法、超類、接口等各種信息,還有一項信息就是常量池。Java的常量池可以存放各種常量信息,不管是編譯期生成的各種字面量,還是需要在運行時決定的符號引用,所以它比一般語言的符號表存儲的信息更加寬泛。
第六,本地方法棧(NativeMethodStack)。它和Java虛擬機棧是非常相似的,支持對本地方法的調(diào)用,也是每個線程都會創(chuàng)建一個。在中,本地方法棧和Java虛擬機棧是在同一塊兒區(qū)域,這完全取決于技術(shù)實現(xiàn)的決定,并未在規(guī)范中強制。
2.什么是Java虛擬機?為什么Java被稱作是無關(guān)平臺的編程語言?
Java虛擬機是一個可以執(zhí)行Java字節(jié)碼的虛擬機進(jìn)程。Java源文件被編譯成能被Java虛擬機執(zhí)行的字節(jié)碼文件。Java被設(shè)計成允許應(yīng)用程序可以運行在任意的平臺,而不需要程序員為每一個平臺單獨重寫或者是重新編譯。Java虛擬機讓這個變?yōu)榭赡?,因為它知道底層硬件平臺的指令長度和其他特性。