想要去阿里面試?你必須得跨過JVM這道坎!-創(chuàng)新互聯(lián)

概述

很多人想要到阿里巴巴、美團(tuán)、京東等互聯(lián)網(wǎng)大公司去面試,但是現(xiàn)在互聯(lián)網(wǎng)大廠面試一般都必定會(huì)考核JVM相關(guān)的知識(shí)積累和實(shí)踐經(jīng)驗(yàn),畢竟線上系統(tǒng)寫好代碼部署之后,每個(gè)工程師都必須關(guān)注JVM相關(guān)的東西,比如OOM、GC等問題.

十年的壺關(guān)網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營(yíng)銷型網(wǎng)站的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整壺關(guān)建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“壺關(guān)網(wǎng)站設(shè)計(jì)”,“壺關(guān)網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

所以一起來看看JVM的最基本的區(qū)域劃分以及工作原理,這個(gè)基本上是互聯(lián)網(wǎng)公司面試必問。

區(qū)域劃分

jvm的區(qū)域劃分如下所示:

想要去阿里面試?你必須得跨過 JVM 這道坎!

大致就是分為:程序計(jì)數(shù)器,虛擬機(jī)棧,堆,方法區(qū),本地方法棧,這幾個(gè)部分。

接下來我們從自己寫好的Java代碼如何通過JVM來運(yùn)行的角度,來分析一下JVM里這些區(qū)域是如何支撐我們的Java代碼跑起來的。

程序計(jì)數(shù)器

假設(shè)我們有如下的一個(gè)類,就是最最基本的一個(gè)HelloWorld而已:

public class HelloWorld {

? ? ? ? public static void main(String[] args) {

? ? ? ? ? ??System.out.println("Hello World");

? ? ? ? }

}

上面那段代碼首先會(huì)存在于 “.java” 后綴的文件里,這個(gè)文件就是java源代碼文件,但是這個(gè)文件是面向我們程序員的,計(jì)算機(jī)他是看不懂你寫的這段代碼的

所以此時(shí)就得通過編譯器,把“.java”后綴的源代碼文件編譯為“.class”后綴的字節(jié)碼文件。

這個(gè)“.class”后綴的字節(jié)碼文件里,存放的就是對(duì)你寫出來的代碼編譯好的字節(jié)碼了,這個(gè)字節(jié)碼才是計(jì)算器可以理解的一種語(yǔ)言,而不是我們寫出來的那一堆代碼。

這個(gè)字節(jié)碼看起來大概是下面這樣的:

想要去阿里面試?你必須得跨過 JVM 這道坎!

這段字節(jié)碼并不是完全對(duì)照著HelloWorld那個(gè)類來寫的,就是給一段示例,讓大家知道“.java”翻譯成的“.class”是大概什么樣子的。

這里比如說“0: aload_0”這樣的,就是“字節(jié)碼指令”,他對(duì)應(yīng)了一條一條的機(jī)器指令,計(jì)算機(jī)只有讀到這種機(jī)器碼指令,才知道具體應(yīng)該要干什么。

比如說字節(jié)碼指令可能會(huì)讓計(jì)算機(jī)從內(nèi)存里讀取某個(gè)數(shù)據(jù),或者把某個(gè)數(shù)據(jù)寫入到內(nèi)存里去,都有可能,各種各樣的指令,就會(huì)指示計(jì)算機(jī)去干各種各樣的事情。

所以現(xiàn)在首先明白一點(diǎn),我們寫好的Java代碼是會(huì)被翻譯成字節(jié)碼的,對(duì)應(yīng)各種字節(jié)碼指令。

那么Java代碼通過JVM跑起來的第一件事情就明確了, 首先Java代碼被編譯出來的字節(jié)碼指令一定會(huì)被一條一條的執(zhí)行,這樣才能實(shí)現(xiàn)我們寫好的代碼被執(zhí)行的效果。

那么在執(zhí)行字節(jié)碼指令的時(shí)候,JVM里的程序計(jì)數(shù)器就是用來記錄每個(gè)線程當(dāng)前執(zhí)行的字節(jié)碼指令的位置的,記錄當(dāng)前線程目前執(zhí)行到了哪一條字節(jié)碼指令。

因?yàn)闀?huì)有多個(gè)線程來并發(fā)的執(zhí)行各種不同的代碼,所以每個(gè)線程都有自己的一個(gè)程序計(jì)數(shù)器,專門記錄當(dāng)前這個(gè)線程目前執(zhí)行到了哪一條字節(jié)碼指令了

下圖更加清晰的展示出了他們之間的關(guān)系。

想要去阿里面試?你必須得跨過 JVM 這道坎!

Java虛擬機(jī)棧

Java代碼在執(zhí)行的時(shí)候,一定是線程來執(zhí)行某個(gè)方法中的代碼,比如哪怕就是上面的那個(gè)最基礎(chǔ)的HelloWorld代碼,也會(huì)有一個(gè)main線程來執(zhí)行main方法里的代碼。

在方法里,經(jīng)常會(huì)定義一些方法內(nèi)的局部變量,比如下面這樣,就在方法里定義了一個(gè)局部變量“name”。

public void sayHello() {

? ? ? ? String name = "hello";

}

所以JVM必須有一塊區(qū)域是來保存每個(gè)方法內(nèi)的局部變量等等數(shù)據(jù)的,這個(gè)區(qū)域就是Java虛擬機(jī)棧

每個(gè)線程都會(huì)去執(zhí)行各種方法的代碼,方法內(nèi)還會(huì)嵌套調(diào)用其他的方法,所以首先每個(gè)線程都有自己的Java虛擬機(jī)棧。

如果線程執(zhí)行了一個(gè)方法,那么就會(huì)被這個(gè)方法調(diào)用創(chuàng)建對(duì)應(yīng)的一個(gè)棧幀,棧幀里就有這個(gè)方法的局部變量表 、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等東西,但是這里別的不太好理解,先理解一個(gè)局部變量就可以。

比如說一個(gè)線程調(diào)用了上面寫的“sayHello”方法,那么就會(huì)為“sayHello”方法創(chuàng)建一個(gè)棧幀,壓入線程自己的Java虛擬機(jī)棧里面去。

在棧幀的局部變量表里就會(huì)有“name”這個(gè)局部變量,下圖展示了這個(gè)過程。

想要去阿里面試?你必須得跨過 JVM 這道坎!

接著如果“sayHello”方法調(diào)用了另外一個(gè)“greeting”方法 ,比如下面那樣的代碼:

想要去阿里面試?你必須得跨過 JVM 這道坎!

那么這個(gè)時(shí)候會(huì)給“greeting”方法又創(chuàng)建一個(gè)棧幀壓入線程的Java虛擬機(jī)棧里,因?yàn)殚_始執(zhí)行“greeting”方法了,而且“greeting”方法的棧幀的局部變量表里會(huì)有一個(gè)“greet”變量,這是“greeting”方法的局部變量。

想要去阿里面試?你必須得跨過 JVM 這道坎!

接著如果“greeting”方法執(zhí)行完畢了,就會(huì)把“greeting”方法對(duì)應(yīng)的棧幀從Java虛擬機(jī)棧里給出棧,然后如果“sayHello”方法也執(zhí)行完畢了,就會(huì)把“sayHello”方法也從Java虛擬機(jī)棧里出棧。

這就是JVM中的 “?Java虛擬機(jī)棧?” 這個(gè)組件的作用,調(diào)用執(zhí)行任何方法的時(shí)候,都會(huì)給方法創(chuàng)建棧幀然后入棧。

而在棧幀里存放了這個(gè)方法對(duì)應(yīng)的局部變量之類的數(shù)據(jù),包括這個(gè)方法執(zhí)行的其他相關(guān)的信息,方法執(zhí)行完畢之后就出棧。

Java堆內(nèi)存

JVM中有另外一個(gè)非常關(guān)鍵的區(qū)域,就是Java堆,這里就是存放我們?cè)诖a中創(chuàng)建的各種對(duì)象的,比如說下面的代碼:

public void teach(String name) {

? ? Student student = new Student(name);

? ? student.study();

}

上面的 “new Student(name)” 這個(gè)代碼就是創(chuàng)建了一個(gè)Student類型的對(duì)象實(shí)例,這個(gè)對(duì)象實(shí)例里面會(huì)包含一些數(shù)據(jù)。

比如說這個(gè)Student的“name”就是屬于這個(gè)對(duì)象實(shí)例的一個(gè)數(shù)據(jù),那么類似Student這樣的對(duì)象,就會(huì)存放在Java堆內(nèi)存里。

Java堆內(nèi)存區(qū)域里會(huì)放入類似Student的對(duì)象,然后方法的棧幀的局部變量表里,這個(gè)引用類型的“student”局部變量就會(huì)存放Student對(duì)象的地址。

相當(dāng)于你可以認(rèn)為局部變量表里的“student”指向了Java堆里的Student對(duì)象。

看下圖會(huì)更加清晰一些。

想要去阿里面試?你必須得跨過 JVM 這道坎!

方法區(qū) / Metaspace

這個(gè)方法區(qū)是在JDK 1.8以前的版本里,代表JVM中的一塊區(qū)域,主要是放類似Student類自己的信息的,平時(shí)用到的各種類的信息,都是放在這個(gè)區(qū)域里的,還會(huì)有一些類似常量池的東西放在這個(gè)區(qū)域里。

但是在JDK 1.8以后,這塊區(qū)域的名字改了,叫做“Metaspace”,可以認(rèn)為是“元數(shù)據(jù)空間”這樣的意思,這里當(dāng)然主要其實(shí)還是存放我們自己寫的各種類相關(guān)的信息。

本地方法棧

其實(shí)在JDK很多底層API里,比如IO相關(guān)的,NIO相關(guān)的,網(wǎng)絡(luò)Socket相關(guān)的,如果大家去看他內(nèi)部的源碼,會(huì)發(fā)現(xiàn)很多地方都不是Java代碼了。

很多地方都會(huì)去走native方法,去調(diào)用本地操作系統(tǒng)里面的一些方法,可能調(diào)用的都是c語(yǔ)言寫的方法,或者一些底層類庫(kù),比如下面這樣的:

public native int hashCode();

在調(diào)用這種native方法的時(shí)候,就會(huì)有線程對(duì)應(yīng)的本地方法棧,這個(gè)里面也是跟Java虛擬機(jī)棧類似的,也是存放各種native方法的局部變量表之類的信息。

堆外內(nèi)存

還有一個(gè)區(qū)域,是不屬于JVM的,通過NIO中的allocateDirect這種API,可以在Java堆外分配內(nèi)存空間。

然后通過Java虛擬機(jī)里的 DirectByteBuffer 來引用和操作堆外內(nèi)存空間,其實(shí)很多技術(shù)都會(huì)用這種方式,因?yàn)橛幸恍﹫?chǎng)景下,堆外內(nèi)存分配可以提升性能。

總結(jié)

最后做一點(diǎn)總結(jié),我們的Java代碼通過JVM來運(yùn)行的時(shí)候,首先一定會(huì)一行一行執(zhí)行編譯好的字節(jié)碼指令。

然后在執(zhí)行的過程中,對(duì)于方法的調(diào)用,會(huì)通過Java虛擬機(jī)棧來為每個(gè)方法創(chuàng)建棧幀入棧和出棧,而且棧幀里有方法的局部變量表

接著對(duì)于對(duì)象的創(chuàng)建,會(huì)分配到Java堆內(nèi)存里去

對(duì)于類信息的存儲(chǔ),會(huì)放在方法區(qū) / Metaspace這樣的區(qū)域里。

另外有兩塊特殊的區(qū)域:

  • 本地方法棧,是執(zhí)行native方法時(shí)候用的棧,跟Java虛擬機(jī)棧是類似的

  • 堆外內(nèi)存,是可以在Java堆外分配內(nèi)存空間來存儲(chǔ)一些對(duì)象。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)站欄目:想要去阿里面試?你必須得跨過JVM這道坎!-創(chuàng)新互聯(lián)
網(wǎng)站網(wǎng)址:http://muchs.cn/article2/dspooc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、企業(yè)建站、網(wǎng)站改版、微信小程序電子商務(wù)、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)