成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

【性能優化】面試官:Java中的對象和數組都是在堆上分配的嗎?

開發 后端
作者個人研發的在高并發場景下,提供的簡單、穩定、可擴展的延遲消息隊列框架,具有精準的定時任務和延遲隊列處理功能。自開源半年多以來,已成功為十幾家中小型企業提供了精準定時調度方案,經受住了生產環境的考驗。

 [[343146]]

作者個人研發的在高并發場景下,提供的簡單、穩定、可擴展的延遲消息隊列框架,具有精準的定時任務和延遲隊列處理功能。自開源半年多以來,已成功為十幾家中小型企業提供了精準定時調度方案,經受住了生產環境的考驗。為使更多童鞋受益,現給出開源框架地址:

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

寫在前面

從開始學習Java的時候,我們就接觸了這樣一種觀點:Java中的對象是在堆上創建的,對象的引用是放在棧里的,那這個觀點就真的是正確的嗎?如果是正確的,那么,面試官為啥會問:“Java中的對象就一定是在堆上分配的嗎?”這個問題呢?看來,我們從接觸Java就被灌輸的這個觀點值得我們懷疑。

關于面試題

標題中的面試題為:Java中的對象和數組都是在堆上分配的嗎?

面試官這樣問,有些小伙伴心里會想:我從一開始學習Java時,就知道了:Java中的對象是在堆上創建的,對象的引用是存儲到棧中的,那Java中的對象和數組肯定是在堆上分配的啊!難道不是嗎?

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

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

面試題答案

首先,我們先給出這個題目的答案,這里我先簡短的回答下這個面試題,后續我們會進行相關分析。

你可以這樣回答:Java中的對象不一定是在堆上分配的,因為JVM通過逃逸分析,能夠分析出一個新對象的使用范圍,并以此確定是否要將這個對象分配到堆上。如果JVM發現某些對象沒有逃逸出方法,就很有可能被優化成在棧上分配。

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

[[343147]]

逃逸分析

逃逸分析的概念

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

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

直接說這些概念,確實有點暈啊,那我們就來兩個示例。

[[343148]]

對象逃逸示例

一種典型的對象逃逸就是:對象被復制給成員變量或者靜態變量,可能被外部使用,此時變量就發生了逃逸。

我們可以用下面的代碼來表示這個現象。

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

在ObjectEscape類中,存在一個成員變量user,我們在init()方法中,創建了一個User類的對象,并將其賦值給成員變量user。此時,對象被復制給了成員變量,可能被外部使用,此時的變量就發生了逃逸。

另一種典型的場景就是:對象通過return語句返回。如果對象通過return語句返回了,此時的程序并不能確定這個對象后續會不會被使用,外部的線程可以訪問到這個變量,此時對象也發生了逃逸。

我們可以用下面的代碼來表示這個現象。

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

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

還沒完,我們繼續看下逃逸分析的優點,以便于小伙伴們能夠更好的理解逃逸分析。

逃逸分析的優點

逃逸分析的優點總體上來說可以分為三個:對象可能分配在棧上、分離對象或標量替換、消除同步鎖。我們可以使用下圖來表示。

對象可能分配在棧上

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

分離對象或標量替換

當JVM通過逃逸分析,確定要將對象分配到棧上時,即時編譯可以將對象打散,將對象替換為一個個很小的局部變量,我們將這個打散的過程叫做標量替換。將對象替換為一個個局部變量后,就可以非常方便的在棧上進行分配了。

同步鎖消除

如果JVM通過逃逸分析,發現一個對象只能從一個線程被訪問到,則訪問這個對象時,可以不加同步鎖。如果程序中使用了synchronized鎖,則JVM會將synchronized鎖消除。

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

要開啟同步消除,需要加上 -XX:+EliminateLocks 參數。因為這個參數依賴逃逸分析,所以同時要打開 -XX:+DoEscapeAnalysis 選項。

所以,并不是所有的對象和數組,都是在堆上進行分配的,由于即時編譯的存在,如果JVM發現某些對象沒有逃逸出方法,就很有可能被優化成在棧上分配。

本文轉載自微信公眾號「冰河技術」,可以通過以下二維碼關注。轉載本文請聯系冰河技術公眾號。 

 

責任編輯:武曉燕 來源: 冰河技術
相關推薦

2018-05-15 16:01:53

對象內存JVM

2021-08-02 08:34:20

React性能優化

2022-07-15 08:22:42

對象符串鍵Symbol

2021-03-16 07:13:07

Java對象存儲

2020-07-28 00:58:20

IP地址子網TCP

2019-11-21 08:40:44

面試官優化性能

2021-03-24 10:25:24

優化VUE性能

2020-11-03 07:00:15

性能優化程序員

2021-05-08 08:35:33

Webpack前端性能

2024-08-08 16:53:17

2015-08-13 10:29:12

面試面試官

2022-10-10 12:31:37

服務器性能

2023-08-11 17:13:39

JavaScrip

2024-06-04 09:02:03

2022-11-19 18:18:22

Spring架構

2020-08-03 07:04:54

測試面試官應用程序

2025-03-26 01:25:00

MySQL優化事務

2024-03-07 17:21:12

HotSpotJVMHot Code

2021-09-08 08:06:57

Redis原子性數據類型

2023-03-08 07:46:53

面試官優化結構體
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99精品欧美一区二区三区综合在线 | 天堂在线中文 | aaaaa毛片| 婷婷午夜天 | 涩涩视频网站在线观看 | 日韩美香港a一级毛片免费 国产综合av | 韩三级在线观看 | 中文字幕一区二区三区精彩视频 | 性欧美hd| 日韩一区精品 | 久久久久无码国产精品一区 | 操操日| 欧美2区 | 日韩国产精品一区二区三区 | 亚州综合一区 | 国产偷久久一级精品60部 | 亚洲黄色网址视频 | 国产亚洲成av人片在线观看桃 | 久久成人国产 | av在线二区| 97久久精品午夜一区二区 | 一区二区三区免费 | 在线播放中文字幕 | 伊人一区 | 视频一区在线 | 亚洲a视频 | 欧美日韩一区二区三区四区五区 | 少妇诱惑av| 91在线网站 | 国产探花在线观看视频 | 久久精品一区二区三区四区 | aaaaaaa片毛片免费观看 | 都市激情亚洲 | 午夜日韩 | 亚洲视频二区 | 国产精品一区二区视频 | 日韩视频在线一区 | 精品久久久一区 | 亚洲精品乱码久久久久久黑人 | 国产精品日日夜夜 | 国产精品亚洲成在人线 |