偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java內(nèi)存區(qū)域全解析:一次被面試官“逼瘋”的回憶錄

開(kāi)發(fā) 前端
每個(gè)咖啡師(線程)都會(huì)拿著一張便簽紙,寫(xiě)著他現(xiàn)在做到哪一步,比如“正在煮咖啡”,“正在加奶油”。這就是程序計(jì)數(shù)器——它記錄當(dāng)前線程正在執(zhí)行哪一行字節(jié)碼指令。


哈嘍大家好,我是你們的老朋友小米,今年31歲,Java搬磚第10年,Bug修復(fù)無(wú)數(shù),面試經(jīng)驗(yàn)滿滿。今天咱不講框架、不講中間件,我們來(lái)聊聊——JVM 內(nèi)存區(qū)域這個(gè)老生常談的面試題。

題目是這樣問(wèn)的:“請(qǐng)你說(shuō)一下 JVM 的主要組成部分以及各自的作用。”

看到這個(gè)問(wèn)題,我眼前一黑,腦子開(kāi)始高速回憶各種堆啊、棧啊、方法區(qū)啊……還真別說(shuō),這問(wèn)題看似基礎(chǔ),答起來(lái)真有點(diǎn)講究。

所以,今天我就來(lái)和大家聊聊,當(dāng)年我是怎么一步一步搞懂這道題,并順利在面試中脫穎而出的——順便,也讓你少走點(diǎn)彎路。

一個(gè)關(guān)于“卡殼”的故事

先說(shuō)說(shuō)我第一次被問(wèn)到這個(gè)問(wèn)題的場(chǎng)景。

那是一家特別講究“基礎(chǔ)扎實(shí)”的互聯(lián)網(wǎng)公司,面試官大叔不茍言笑,一開(kāi)口就問(wèn):

“JVM的主要內(nèi)存區(qū)域有哪些?能說(shuō)下它們各自的作用嗎?”

我當(dāng)時(shí)一愣,“呃……堆、棧、方法區(qū)、程序計(jì)數(shù)器,還有本地方法棧?”

大叔點(diǎn)點(diǎn)頭:“繼續(xù)?!?/p>

我繼續(xù):“嗯……堆是用來(lái)存放對(duì)象實(shí)例的,棧用來(lái)存放局部變量……方法區(qū)用來(lái)存放類信息……”

說(shuō)到這,我就卡殼了。

那個(gè)瞬間,空氣凝固了三秒鐘,我的腦門(mén)開(kāi)始冒汗。面試官嘆了口氣,說(shuō):

“你還是回去好好復(fù)習(xí)一下《深入理解JVM》吧?!?/p>

那天我落荒而逃,回到家就開(kāi)始痛定思痛,打開(kāi)《深入理解Java虛擬機(jī)》,開(kāi)啟了長(zhǎng)達(dá)三晚的“Java內(nèi)存苦修”模式。

JVM 內(nèi)存結(jié)構(gòu)大揭秘

要搞懂 JVM 的內(nèi)存區(qū)域,先來(lái)認(rèn)識(shí)一下 JVM 的整體結(jié)構(gòu)(放心,不用背圖,我用故事講清楚):

JVM 就像一個(gè)智能大管家,掌管著內(nèi)存的調(diào)配,分成幾個(gè)“分區(qū)”來(lái)處理不同的事兒。它的主要組成包括:

圖片

接下來(lái)我用一個(gè)比喻幫你理解。

用“咖啡師工作室”類比 JVM 內(nèi)存區(qū)域

想象 JVM 是一個(gè)咖啡店的工作室,里面有一位超級(jí)忙碌的咖啡師,他每天需要處理各種訂單、材料、配方和機(jī)器指令。我們把這些比喻一下:

1、程序計(jì)數(shù)器:你的“備忘小便簽”

每個(gè)咖啡師(線程)都會(huì)拿著一張便簽紙,寫(xiě)著他現(xiàn)在做到哪一步,比如“正在煮咖啡”,“正在加奶油”。這就是程序計(jì)數(shù)器——它記錄當(dāng)前線程正在執(zhí)行哪一行字節(jié)碼指令。

它是線程私有的,因?yàn)槊總€(gè)咖啡師做的事不一樣,不能共用便簽。

2、Java虛擬機(jī)棧:你的“工具箱”

每個(gè)咖啡師有一個(gè)工具箱,里面有當(dāng)前正在處理訂單的方法調(diào)用棧幀,裝著局部變量(杯子、糖、勺子)、返回地址等。

方法一調(diào)用,就入棧;方法一執(zhí)行完,就出棧。棧深不夠,就棧溢出了(StackOverflowError)。

3、本地方法棧:備用老設(shè)備

有時(shí)候需要用上古機(jī)器來(lái)完成任務(wù),比如一個(gè)只能通過(guò)老式電話撥號(hào)器完成的任務(wù),這些“非Java”的方法叫做本地方法(Native)。本地方法棧專門(mén)為它們服務(wù)。

4、堆:所有原材料的大倉(cāng)庫(kù)

你要制作一杯拿鐵,需要咖啡豆、牛奶、杯子等等,這些對(duì)象都統(tǒng)一放在堆里。

Java中所有對(duì)象實(shí)例和數(shù)組都放在堆里。JVM的垃圾回收器(GC)主要盯著這塊區(qū)域,及時(shí)回收用不到的原材料。

5、方法區(qū)(元空間):配方手冊(cè)與規(guī)則存檔

這里是存儲(chǔ)類的結(jié)構(gòu)信息、方法、常量池、靜態(tài)變量的地方。以前叫方法區(qū),JDK8之后移到了本地內(nèi)存中,叫元空間(Metaspace)。

每一塊區(qū)域的深度八卦

來(lái),我們一個(gè)個(gè)深入聊聊它們到底“藏”了多少秘密。

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

  • 非常小,但很重要。
  • 如果線程切換,就靠它記錄上一次執(zhí)行的位置。
  • 它是唯一一個(gè)不會(huì)內(nèi)存溢出的區(qū)域!

2、虛擬機(jī)棧

  • 方法每調(diào)用一次,就生成一個(gè)棧幀。
  • 局部變量表、操作數(shù)棧、方法返回地址等都在里面。
  • 如果方法遞歸太深,可能會(huì)導(dǎo)致StackOverflowError。
  • 如果棧擴(kuò)展失敗,則可能是OutOfMemoryError。

3、本地方法棧

  • 用得少,但別小看。
  • JNI調(diào)用C函數(shù)時(shí)就要靠它。
  • 異常一般不容易發(fā)生,除非調(diào)用了大量 native 方法。

4、堆(Heap)

  • Java內(nèi)存最大的一塊。
  • 所有的 new 出來(lái)的對(duì)象都在這里。
  • GC經(jīng)常掃它,有“新生代”“老年代”的分代概念。
  • 如果對(duì)象太多來(lái)不及回收,就會(huì)出現(xiàn)OutOfMemoryError: Java heap space。

5、方法區(qū)(元空間)

  • 存儲(chǔ)類元數(shù)據(jù)、常量池、靜態(tài)變量。
  • JDK 8 之前叫永久代(PermGen),容易報(bào)OutOfMemoryError: PermGen space。
  • JDK 8 之后改為元空間,直接用本地內(nèi)存,更靈活,但也可能爆OutOfMemoryError: Metaspace。

如何在面試中回答這個(gè)問(wèn)題?

回到那個(gè)面試官的問(wèn)題——“說(shuō)一下 JVM 的主要組成部分及其作用?”

我在第二次面試時(shí),這樣回答的:

“JVM主要內(nèi)存結(jié)構(gòu)可以分為五大部分:


  • 程序計(jì)數(shù)器(線程私有):記錄字節(jié)碼指令執(zhí)行位置;
  • Java虛擬機(jī)棧(線程私有):存儲(chǔ)方法調(diào)用相關(guān)的棧幀、局部變量;
  • 本地方法棧(線程私有):調(diào)用native方法時(shí)使用;
  • Java堆(線程共享):存儲(chǔ)所有對(duì)象實(shí)例,是GC關(guān)注的重點(diǎn);
  • 方法區(qū)/元空間(線程共享):保存類結(jié)構(gòu)、靜態(tài)變量、常量池等元信息。


其中,堆和方法區(qū)是線程共享的,其余是線程私有的。GC主要關(guān)注堆區(qū),JDK8后永久代被元空間替代。”

大叔聽(tīng)完,點(diǎn)了點(diǎn)頭,說(shuō):“這個(gè)問(wèn)題你答得挺清楚的。”

我心里那塊大石頭總算落地。

小結(jié):一圖勝千言

最后我分享給大家一個(gè)總結(jié)圖:

圖片圖片

記住關(guān)鍵點(diǎn):線程共享 vs 線程私有、GC關(guān)注堆、JDK8 改了方法區(qū)……

END

那場(chǎng)失敗的面試,曾讓我對(duì) JVM 的印象變得“又怕又恨”。但現(xiàn)在回頭看,它成了我技術(shù)成長(zhǎng)的分水嶺。

如果你也曾在 JVM 面前崩潰過(guò),別氣餒,它確實(shí)難,但也值得!

責(zé)任編輯:武曉燕 來(lái)源: 軟件求生
相關(guān)推薦

2020-05-12 11:05:54

MySQL索引數(shù)據(jù)庫(kù)

2023-04-07 19:25:04

后端開(kāi)發(fā)

2012-06-07 09:00:06

2021-07-05 22:09:53

面試官CollectionsJDK7

2020-04-09 08:47:38

Java對(duì)象線程

2013-04-06 18:52:20

2020-08-03 07:04:54

測(cè)試面試官應(yīng)用程序

2021-03-10 08:05:10

Nginx面試并發(fā)

2024-04-17 08:18:22

MyBatis批量插入SQL

2020-06-22 07:47:46

提交面試官訂單

2012-09-07 14:30:31

工作回憶錄

2013-08-28 11:21:05

2024-02-22 15:36:23

Java內(nèi)存模型線程

2021-12-17 07:30:42

排序算法效率

2023-12-25 09:03:33

MySQL索引數(shù)據(jù)庫(kù)

2021-03-17 08:39:24

作用域作用域鏈JavaScript

2021-03-16 22:25:06

作用域鏈作用域JavaScript

2022-06-07 12:03:33

Java內(nèi)存模型

2019-10-21 09:56:37

MySQLCOUNTInnoDB

2020-11-06 07:11:40

內(nèi)存虛擬Redis
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)