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

【性能優(yōu)化】面試官:Java中的對(duì)象和數(shù)組都是在堆上分配的嗎?

開發(fā) 后端
作者個(gè)人研發(fā)的在高并發(fā)場(chǎng)景下,提供的簡(jiǎn)單、穩(wěn)定、可擴(kuò)展的延遲消息隊(duì)列框架,具有精準(zhǔn)的定時(shí)任務(wù)和延遲隊(duì)列處理功能。自開源半年多以來,已成功為十幾家中小型企業(yè)提供了精準(zhǔn)定時(shí)調(diào)度方案,經(jīng)受住了生產(chǎn)環(huán)境的考驗(yàn)。

 [[343146]]

作者個(gè)人研發(fā)的在高并發(fā)場(chǎng)景下,提供的簡(jiǎn)單、穩(wěn)定、可擴(kuò)展的延遲消息隊(duì)列框架,具有精準(zhǔn)的定時(shí)任務(wù)和延遲隊(duì)列處理功能。自開源半年多以來,已成功為十幾家中小型企業(yè)提供了精準(zhǔn)定時(shí)調(diào)度方案,經(jīng)受住了生產(chǎn)環(huán)境的考驗(yàn)。為使更多童鞋受益,現(xiàn)給出開源框架地址:

https://github.com/sunshinelyz/mykit-delay

寫在前面

從開始學(xué)習(xí)Java的時(shí)候,我們就接觸了這樣一種觀點(diǎn):Java中的對(duì)象是在堆上創(chuàng)建的,對(duì)象的引用是放在棧里的,那這個(gè)觀點(diǎn)就真的是正確的嗎?如果是正確的,那么,面試官為啥會(huì)問:“Java中的對(duì)象就一定是在堆上分配的嗎?”這個(gè)問題呢?看來,我們從接觸Java就被灌輸?shù)倪@個(gè)觀點(diǎn)值得我們懷疑。

關(guān)于面試題

標(biāo)題中的面試題為:Java中的對(duì)象和數(shù)組都是在堆上分配的嗎?

面試官這樣問,有些小伙伴心里會(huì)想:我從一開始學(xué)習(xí)Java時(shí),就知道了:Java中的對(duì)象是在堆上創(chuàng)建的,對(duì)象的引用是存儲(chǔ)到棧中的,那Java中的對(duì)象和數(shù)組肯定是在堆上分配的啊!難道不是嗎?

如果你這樣回答,就會(huì)被直接Pass掉。

或許有些小伙伴還是不太明白,那我們繼續(xù)往下看。

面試題答案

首先,我們先給出這個(gè)題目的答案,這里我先簡(jiǎn)短的回答下這個(gè)面試題,后續(xù)我們會(huì)進(jìn)行相關(guān)分析。

你可以這樣回答:Java中的對(duì)象不一定是在堆上分配的,因?yàn)镴VM通過逃逸分析,能夠分析出一個(gè)新對(duì)象的使用范圍,并以此確定是否要將這個(gè)對(duì)象分配到堆上。如果JVM發(fā)現(xiàn)某些對(duì)象沒有逃逸出方法,就很有可能被優(yōu)化成在棧上分配。

這里,我們接觸了一個(gè)新名詞:逃逸分析。相信很多小伙伴不是很明白,那我們繼續(xù)往下看。

[[343147]]

逃逸分析

逃逸分析的概念

先以官方的形式來說下什么是逃逸分析。逃逸分析就是:一種確定指針動(dòng)態(tài)范圍的靜態(tài)分析,它可以分析在程序的哪些地方可以訪問到指針。

在JVM的即時(shí)編譯語(yǔ)境下,逃逸分析將判斷新建的對(duì)象是否逃逸。即時(shí)編譯判斷對(duì)象是否逃逸的依據(jù):一種是對(duì)象是否被存入堆中(靜態(tài)字段或者堆中對(duì)象的實(shí)例字段),另一種就是對(duì)象是否被傳入未知代碼。

直接說這些概念,確實(shí)有點(diǎn)暈啊,那我們就來兩個(gè)示例。

[[343148]]

對(duì)象逃逸示例

一種典型的對(duì)象逃逸就是:對(duì)象被復(fù)制給成員變量或者靜態(tài)變量,可能被外部使用,此時(shí)變量就發(fā)生了逃逸。

我們可以用下面的代碼來表示這個(gè)現(xiàn)象。

  1. /** 
  2.  * @author binghe 
  3.  * @description 對(duì)象逃逸示例1 
  4.  */ 
  5. public class ObjectEscape{ 
  6.     private User user
  7.     public void init(){ 
  8.         user = new User(); 
  9.     } 

在ObjectEscape類中,存在一個(gè)成員變量user,我們?cè)趇nit()方法中,創(chuàng)建了一個(gè)User類的對(duì)象,并將其賦值給成員變量user。此時(shí),對(duì)象被復(fù)制給了成員變量,可能被外部使用,此時(shí)的變量就發(fā)生了逃逸。

另一種典型的場(chǎng)景就是:對(duì)象通過return語(yǔ)句返回。如果對(duì)象通過return語(yǔ)句返回了,此時(shí)的程序并不能確定這個(gè)對(duì)象后續(xù)會(huì)不會(huì)被使用,外部的線程可以訪問到這個(gè)變量,此時(shí)對(duì)象也發(fā)生了逃逸。

我們可以用下面的代碼來表示這個(gè)現(xiàn)象。

  1. /** 
  2.  * @author binghe 
  3.  * @description 對(duì)象逃逸示例2 
  4.  */ 
  5. public class ObjectReturn{ 
  6.     public User createUser(){ 
  7.         User user = new User(); 
  8.         return user
  9.     } 

給出兩個(gè)示例,相信小伙伴們對(duì)JVM的逃逸分析多少有點(diǎn)了解了吧,沒錯(cuò),JVM通過逃逸分析,能夠分析出新對(duì)象的使用范圍,從而決定新對(duì)象是否要在堆上進(jìn)行分配。

還沒完,我們繼續(xù)看下逃逸分析的優(yōu)點(diǎn),以便于小伙伴們能夠更好的理解逃逸分析。

逃逸分析的優(yōu)點(diǎn)

逃逸分析的優(yōu)點(diǎn)總體上來說可以分為三個(gè):對(duì)象可能分配在棧上、分離對(duì)象或標(biāo)量替換、消除同步鎖。我們可以使用下圖來表示。

對(duì)象可能分配在棧上

JVM通過逃逸分析,分析出新對(duì)象的使用范圍,就可能將對(duì)象在棧上進(jìn)行分配。棧分配可以快速地在棧幀上創(chuàng)建和銷毀對(duì)象,不用再將對(duì)象分配到堆空間,可以有效地減少 JVM 垃圾回收的壓力。

分離對(duì)象或標(biāo)量替換

當(dāng)JVM通過逃逸分析,確定要將對(duì)象分配到棧上時(shí),即時(shí)編譯可以將對(duì)象打散,將對(duì)象替換為一個(gè)個(gè)很小的局部變量,我們將這個(gè)打散的過程叫做標(biāo)量替換。將對(duì)象替換為一個(gè)個(gè)局部變量后,就可以非常方便的在棧上進(jìn)行分配了。

同步鎖消除

如果JVM通過逃逸分析,發(fā)現(xiàn)一個(gè)對(duì)象只能從一個(gè)線程被訪問到,則訪問這個(gè)對(duì)象時(shí),可以不加同步鎖。如果程序中使用了synchronized鎖,則JVM會(huì)將synchronized鎖消除。

這里,需要注意的是:這種情況針對(duì)的是synchronized鎖,而對(duì)于Lock鎖,則JVM并不能消除。

要開啟同步消除,需要加上 -XX:+EliminateLocks 參數(shù)。因?yàn)檫@個(gè)參數(shù)依賴逃逸分析,所以同時(shí)要打開 -XX:+DoEscapeAnalysis 選項(xiàng)。

所以,并不是所有的對(duì)象和數(shù)組,都是在堆上進(jìn)行分配的,由于即時(shí)編譯的存在,如果JVM發(fā)現(xiàn)某些對(duì)象沒有逃逸出方法,就很有可能被優(yōu)化成在棧上分配。

本文轉(zhuǎn)載自微信公眾號(hào)「冰河技術(shù)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系冰河技術(shù)公眾號(hào)。 

 

責(zé)任編輯:武曉燕 來源: 冰河技術(shù)
相關(guān)推薦

2018-05-15 16:01:53

對(duì)象內(nèi)存JVM

2022-07-15 08:22:42

對(duì)象符串鍵Symbol

2021-08-02 08:34:20

React性能優(yōu)化

2021-03-16 07:13:07

Java對(duì)象存儲(chǔ)

2020-07-28 00:58:20

IP地址子網(wǎng)TCP

2019-11-21 08:40:44

面試官優(yōu)化性能

2021-03-24 10:25:24

優(yōu)化VUE性能

2020-11-03 07:00:15

性能優(yōu)化程序員

2021-05-08 08:35:33

Webpack前端性能

2024-08-08 16:53:17

2015-08-13 10:29:12

面試面試官

2023-08-11 17:13:39

JavaScrip

2024-06-04 09:02:03

2022-10-10 12:31:37

服務(wù)器性能

2022-11-19 18:18:22

Spring架構(gòu)

2025-03-26 01:25:00

MySQL優(yōu)化事務(wù)

2024-03-07 17:21:12

HotSpotJVMHot Code

2020-08-03 07:04:54

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

2021-09-08 08:06:57

Redis原子性數(shù)據(jù)類型

2023-03-08 07:46:53

面試官優(yōu)化結(jié)構(gòu)體
點(diǎn)贊
收藏

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