自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試篇:虛擬機(jī)棧5連問(wèn)?一聽(tīng)心里就樂(lè)了

云計(jì)算 虛擬化
假如我們的棧幀不固定,設(shè)置為動(dòng)態(tài)擴(kuò)展的,那在我們的內(nèi)存不足時(shí),也就沒(méi)有足夠的內(nèi)存來(lái)支持棧的擴(kuò)展,這個(gè)時(shí)候就會(huì)出現(xiàn)OOM異常,即內(nèi)存溢出問(wèn)題。

[[399686]]

面試路上

“滴,滴滴......”師傅我們到哪了?我還要趕著面試呢。

「師傅:」 快了快了,下個(gè)路口就到了。真是服了這幫人了,不會(huì)開(kāi)車(chē)凈往里湊。

聽(tīng)著司機(jī)師傅的抱怨聲,不禁想起首打油詩(shī):滿目尾燈紅,耳盈刺笛聲。心憂遲到久,頹首似雷轟。

一下車(chē)趕緊小跑就進(jìn)了富麗堂皇的酒店,不不不,是商務(wù)樓,這大廳有點(diǎn)氣派,讓我有點(diǎn)想入非非呀。

面試經(jīng)過(guò)

“咚咚咚”,“請(qǐng)進(jìn)”。

「面試官:」 小伙子長(zhǎng)得挺帥呀,年輕人就是有活力,來(lái)先做個(gè)簡(jiǎn)單的自我介紹吧。

「阿Q:」 面試官你好,My name is “影流之主”,來(lái)自艾歐尼亞,是LOL中的最強(qiáng)中單(不接受反駁),論單殺沒(méi)有服過(guò)誰(shuí)。我的口頭禪是“無(wú)形之刃,最為致命”,當(dāng)然你也可以叫我阿Q,這是我的簡(jiǎn)歷。

「面試官:」 阿Q,那咱也不寒暄了,直接切正題吧。看你jvm寫(xiě)的知識(shí)點(diǎn)最多,那就先說(shuō)一下你對(duì)虛擬機(jī)棧的理解吧。

「阿Q:」 內(nèi)心OS:這波可以吹X了???..咳...虛擬機(jī)棧早期也叫java棧,是在jvm的運(yùn)行時(shí)數(shù)據(jù)區(qū)存在的一塊內(nèi)存區(qū)域。它是線程私有的,隨線程創(chuàng)建而創(chuàng)建,隨線程消亡而結(jié)束。

嗯。。。假裝想一下??

眾所周知,棧只有進(jìn)棧和出棧兩種操作,所以它是一種快速有效的分配存儲(chǔ)方式。對(duì)于它來(lái)說(shuō),它不存在垃圾回收問(wèn)題,但是它的大小是動(dòng)態(tài)的或者固定不變的,因此它會(huì)存在棧溢出或者內(nèi)存溢出問(wèn)題......

「面試官:」 打斷一下啊,你剛才說(shuō)會(huì)存在棧溢出和內(nèi)存溢出問(wèn)題,那你能分別說(shuō)一下為什么會(huì)出現(xiàn)這種情況嗎?

「阿Q:」 可以可以,我們知道虛擬機(jī)棧由棧幀組成,每一個(gè)方法的調(diào)用都對(duì)應(yīng)著一個(gè)棧幀的入棧。我們可以通過(guò)-Xss參數(shù)來(lái)設(shè)置棧的大小,假設(shè)我們?cè)O(shè)置的虛擬機(jī)棧大小很小,當(dāng)我們調(diào)用的方法過(guò)多,也就是棧幀過(guò)多的話,就會(huì)出現(xiàn)StackOverflowError,即棧溢出問(wèn)題。

假如我們的棧幀不固定,設(shè)置為動(dòng)態(tài)擴(kuò)展的,那在我們的內(nèi)存不足時(shí),也就沒(méi)有足夠的內(nèi)存來(lái)支持棧的擴(kuò)展,這個(gè)時(shí)候就會(huì)出現(xiàn)OOM異常,即內(nèi)存溢出問(wèn)題。

「面試官:」 嗯嗯(點(diǎn)頭狀),示意小伙子思路很清晰呀,那你剛才說(shuō)到棧幀設(shè)置的太小會(huì)導(dǎo)致棧幀溢出問(wèn)題,那我們?cè)O(shè)置的大點(diǎn)不就可以完全避免棧溢出了嘛。

「阿Q:」 一聽(tīng)就是要給我挖坑呀,像我們一般都比較崇尚中庸之道,所以一聽(tīng)到這種絕對(duì)的問(wèn)題,必須機(jī)靈點(diǎn):不不不,調(diào)整棧的大小只可以「延緩」棧溢出的時(shí)間或者說(shuō)減少棧溢出的風(fēng)險(xiǎn)。

舉個(gè)例子吧

假如一個(gè)業(yè)務(wù)邏輯的方法調(diào)用需要5000次,但是此時(shí)拋出了棧溢出的錯(cuò)誤。我們可以通過(guò)設(shè)置-Xss來(lái)獲取更大的??臻g,使得調(diào)用在7000次時(shí)才會(huì)溢出。此時(shí)調(diào)整棧大小就變得很有意義,因?yàn)檫@樣就會(huì)使得業(yè)務(wù)能正常支持。

那假如是有「死遞歸」的情況則無(wú)論怎么提高棧大小都會(huì)溢出,這樣也就沒(méi)有任何意義了。

「面試官:」 好的,那你看一下這個(gè)簡(jiǎn)單的小程序,你能大體說(shuō)一下它在內(nèi)存中的執(zhí)行過(guò)程嗎?

  1.  public void test() { 
  2.       byte i = 15; 
  3.       int j = 8; 
  4.       int k = i + j; 

來(lái)張圖,便于大家更好地理解

「阿Q:」 先把該代碼編譯一下,然后查看它的字節(jié)碼文件。如上圖中左邊所示,執(zhí)行過(guò)程如下:

  1. 首先將要執(zhí)行的指令地址0存放到PC寄存器中,此時(shí),局部變量表和操作數(shù)棧的數(shù)據(jù)為空;
  2. 當(dāng)執(zhí)行第一條指令bipush時(shí),將操作數(shù)15放入操作數(shù)棧中,然后將PC寄存器的值置為下一條指令的執(zhí)行地址,即2;
  3. 當(dāng)執(zhí)行指令地址為2的操作指令時(shí),將操作數(shù)棧中的數(shù)據(jù)取出來(lái),存到局部變量表的1位置,因?yàn)樵摲椒ㄊ菍?shí)例方法,所以0位置存的是this的值,PC寄存器中的值變?yōu)?;
  4. 同步驟2和3將8先放入操作數(shù)棧,然后取出來(lái)存到局部變量表中,PC寄存器中的值也由3->5->6;
  5. 當(dāng)執(zhí)行到地址指令為6、7、8時(shí),將局部變量表中索引位置為1和2的數(shù)據(jù)重新加載到操作數(shù)棧中并進(jìn)行iadd加操作,將得到的結(jié)果值存到操作數(shù)棧中,PC寄存器中的值也由6->7->8->9;
  6. 執(zhí)行操作指令istore_3,將操作數(shù)棧中的數(shù)據(jù)取出存到局部變量表中索引為3的位置,執(zhí)行return指令,方法結(jié)束。

「面試官:」 內(nèi)心OS:這小子貌似還可以呀。說(shuō)的還不錯(cuò),那你能說(shuō)一下方法中定義的局部變量是否線程安全嗎?

「阿Q:」 那我再用幾個(gè)例子來(lái)說(shuō)一下吧。

  1. public class LocalParaSafeProblem { 
  2.  
  3.  
  4.     /** 
  5.      * 線程安全的 
  6.      * 雖然StringBuilder本身線程不安全, 
  7.      * 但s1 變量只存在于這個(gè)棧幀的局部變量表中, 
  8.      * 因?yàn)闂敲總€(gè)線程獨(dú)立的一份, 
  9.      * 所以這里的s1是線程安全的 
  10.      */ 
  11.     public static void method01() { 
  12.         // 線程內(nèi)部創(chuàng)建的,屬于局部變量 
  13.         StringBuilder s1 = new StringBuilder(); 
  14.         s1.append("a"); 
  15.         s1.append("b"); 
  16.     } 
  17.  
  18.     /** 
  19.      * 線程不安全 
  20.      * 因?yàn)榇藭r(shí)StringBuilder是作為參數(shù)傳入, 
  21.      * 外部的其他線程也可以訪問(wèn),所以線程不安全 
  22.      */ 
  23.     public static void method02(StringBuilder stringBuilder) { 
  24.         stringBuilder.append("a"); 
  25.         stringBuilder.append("b"); 
  26.     } 
  27.  
  28.     /** 
  29.      * 線程不安全 
  30.      * 此時(shí)StringBuilder被多個(gè)線程同時(shí)操作 
  31.      */ 
  32.     public static void method03() { 
  33.         StringBuilder stringBuilder = new StringBuilder(); 
  34.         new Thread(() -> { 
  35.             stringBuilder.append("a"); 
  36.             stringBuilder.append("b"); 
  37.         }, "t1").start(); 
  38.  
  39.         method02(stringBuilder); 
  40.     } 
  41.  
  42.     /** 
  43.      * 線程不安全 
  44.      * 因?yàn)榇藭r(shí)方法將StringBuilder返回出去了 
  45.      * 外面的其他線程可以直接修改StringBuilder這個(gè)引用了所以不安全 
  46.      */ 
  47.     public static StringBuilder method04() { 
  48.         StringBuilder stringBuilder = new StringBuilder(); 
  49.         stringBuilder.append("a"); 
  50.         stringBuilder.append("b"); 
  51.         return stringBuilder; 
  52.     } 
  53.  
  54.  
  55.     /** 
  56.      * StringBuilder是線程安全的 
  57.      * 此時(shí)stringBuilder值在當(dāng)前棧幀的局部變量表中存在, 
  58.      * 其他線程無(wú)法訪問(wèn)到該引用, 
  59.      * 方法執(zhí)行完成之后此時(shí)局部變量表中的stringBuilder的就銷(xiāo)毀了 
  60.      * 返回的stringBuilder.toString()線程不安全 
  61.      * 最后的返回值將toString返回之后,其他線程可以操作而String本身是線程不安全的。 
  62.      */ 
  63.     public static String method05() { 
  64.         StringBuilder stringBuilder = new StringBuilder(); 
  65.         stringBuilder.append("a"); 
  66.         stringBuilder.append("b"); 
  67.         return stringBuilder.toString(); 
  68.     } 

看到這估計(jì)會(huì)有點(diǎn)繞,那我就總結(jié)一下吧:如果對(duì)象是在方法內(nèi)部產(chǎn)生且在內(nèi)部消亡,不會(huì)返回到外部就不存在線程安全問(wèn)題;反之如果類(lèi)本身線程不安全的話就存在線程安全問(wèn)題。

「面試官:」 不錯(cuò)不錯(cuò),有理有據(jù),那你再說(shuō)說(shuō)你對(duì)堆內(nèi)存的理解吧。

「阿Q:」 唉,今天太累了,說(shuō)了一天這個(gè)了,不想說(shuō)了。

「面試官:」 那好吧,那我們今天先到這吧,回去等通知吧。

本文轉(zhuǎn)載自微信公眾號(hào)「阿Q說(shuō)代碼」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系阿Q說(shuō)代碼公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 阿Q說(shuō)代碼
相關(guān)推薦

2022-06-02 07:11:13

JVMJava

2021-09-29 09:00:19

Linux虛擬機(jī)CentOS

2023-02-07 06:47:58

JVM 模塊Java 虛擬機(jī)

2021-04-14 18:58:01

虛擬機(jī) Java內(nèi)存

2023-07-27 06:59:30

Native線程數(shù)據(jù)結(jié)構(gòu)

2023-02-09 08:48:47

Java虛擬機(jī)

2018-09-11 14:47:51

面試Java虛擬機(jī)

2020-06-03 15:07:01

Java虛擬機(jī)棧JVM

2024-03-26 07:30:07

Java虛擬機(jī)源文件

2012-05-18 10:22:23

2018-02-24 12:54:51

Java虛擬機(jī)面試

2022-06-06 08:00:59

Kvm虛擬機(jī)磁盤(pán)

2009-09-25 15:46:46

虛擬機(jī)軟件

2010-07-26 09:02:38

2013-07-17 09:32:58

2019-07-31 15:56:57

Jvm虛擬機(jī)Content

2010-11-17 16:45:41

虛擬機(jī)

2020-10-21 08:16:37

Java基礎(chǔ)入門(mén)篇

2021-07-12 07:08:52

TCP協(xié)議面試

2021-11-09 09:30:52

OkHttp面試Android
點(diǎn)贊
收藏

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