哦哇資訊網

阿里面試官:Java物件一定是在堆中分配嗎?我被秒殺的體無完膚

由 微點趣味車評 發表于 娛樂2021-12-09

面試經歷

記得幾年前有一次

阿里

去面試,問到了這麼一個問題:

Java中的物件都是在堆中分配嗎?說明為什麼!

當時我被問得一臉懵逼,瞬間被秒殺得體無完膚,當時我壓根就不知道他在考什麼知識點,難道物件不是在堆中分配嗎?最後就沒然後了,回去等通知了。

物件的分配

幾乎所有的物件在堆中進行分配,這個是大家經常看到的一句話,但是這句話中並不意味著所有,JVM中物件是可以在棧中進行分配,但是前提是需要判斷逃逸狀態。

物件逃逸狀態 1、全域性逃逸(GlobalEscape)

即一個物件的作用範圍逃出了當前方法或者當前執行緒,有以下幾種場景:

物件是一個靜態變數

物件是一個已經發生逃逸的物件

物件作為當前方法的返回值

2、引數逃逸(ArgEscape)

即一個物件被作為方法引數傳遞或者被引數引用,但在呼叫過程中不會發生全域性逃逸,這個狀態是透過被調方法的位元組碼確定的。

3、沒有逃逸

即方法中的物件沒有發生逃逸。

逃逸分析

程式碼

public class EscapeAnalysisTest { public static void main(String[] args) throws Exception { long start = System。currentTimeMillis(); for (int i = 0; i

這段程式碼在呼叫的過程中 myboject這個物件屬於全域性逃逸,JVM可以做棧上分配

然後透過開啟和關閉DoEscapeAnalysis開關觀察不同。

開啟逃逸分析(JVM預設開啟)

檢視執行速度

阿里面試官:Java物件一定是在堆中分配嗎?我被秒殺的體無完膚

關閉逃逸分析

檢視執行速度

阿里面試官:Java物件一定是在堆中分配嗎?我被秒殺的體無完膚

測試結果可見,開啟逃逸分析對程式碼的執行效能有很大的影響!那為什麼有這個影響?

逃逸分析

如果是逃逸分析出來的物件可以在棧上分配的話,那麼該物件的生命週期就跟隨執行緒了,就不需要垃圾回收,如果是頻繁的呼叫此方法則可以得到很大的效能提高。

採用了逃逸分析後,滿足逃逸的物件在棧上分配

阿里面試官:Java物件一定是在堆中分配嗎?我被秒殺的體無完膚

沒有開啟逃逸分析,物件都在堆上分配,會頻繁觸發垃圾回收(垃圾回收會影響系統性能),導致程式碼執行慢

阿里面試官:Java物件一定是在堆中分配嗎?我被秒殺的體無完膚

程式碼驗證

開啟GC列印日誌

-XX:+PrintGC

開啟逃逸分析

阿里面試官:Java物件一定是在堆中分配嗎?我被秒殺的體無完膚

可以看到沒有GC日誌

關閉逃逸分析

阿里面試官:Java物件一定是在堆中分配嗎?我被秒殺的體無完膚

可以看到關閉了逃逸分析,JVM在頻繁的進行垃圾回收(GC),正是這一塊的操作導致效能有較大的差別。

總結

JVM是很多面試官非常喜歡問的。但是有些面試官的問題非常刁鑽,因為 JVM 的知識體系博大精深,如果你沒有把握就不要輕易回答。有些知識是需要實踐才能體驗到,心平氣和的講解這些知識點,會讓你在面試中掌握主動地位。

TAG: 逃逸物件JVM分配開啟