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

在 Java 里找對象需要見家長考核嗎?

開發(fā) 開發(fā)工具 后端
程序員們經常會調侃說,現在找對象太難了,看我們代碼里找對象多容易,想要的時候就new 一個。今天一起看下, 代碼里 new 一個對象,都有哪些過程。

程序員們經常會調侃說,現在找對象太難了,看我們代碼里找對象多容易,想要的時候就new 一個。

玩笑歸玩笑,實際對代碼來說,對象不是你想 new 想new就能 new 的。像真實社會里會見見家長,了解家庭等等,在實際的代碼運行中,一個也不少。一個對象 new 的過程,也是要經過層層「 考核」的。

[[323962]]

今天一起看下, 代碼里 new 一個對象,都有哪些過程。

在 Java 開發(fā)中,你能想到的對象創(chuàng)建過程,最直接體現的是代碼里new MyObject()。

然而這只是「冰山一角」。

在虛擬機執(zhí)行中,要在堆里給對象空間吧。比如最容易想到的,你需要的對象有點大,在new的時候,內存不夠了。

又或者當前創(chuàng)建對象的 Class 繼承或者組合了其它的類或接口,這些在類加載過程中沒有找到,和現實中的家長不同意也差不多。

還有多線程環(huán)境下,對象可能過早的「逸出」,就像家長讓對象去相親一樣,讓其他線程可以修改對象的值,讓你意想不到。

...

你以為只是輕松的 new 了一下, 但JVM 還真干了不少事兒吧~ JVM 默默承擔了這一切,化難度、復雜于無形。

比如為了讓你更快的有對象, JVM 會看情況能不能「快速分配」,符合條件甚至還有專有內存空間,保證不受其他線程的影響等等, 如果還是不行只能慢速了。

一個對象的創(chuàng)建基本流程如下:

  •  獲得對象在常量池中的索引以及對應的常量池項
  • 驗證類是否已被解析
  • 獲取他對應的 instanceKlass,保證已經完成初始化
  • 如果滿足條件,進入快速分配流程
  • 不滿足或快速分配失敗,進入慢速分配,再進行類的初始化,實例分配

總結起來似乎也只有兩步:

  • 給對象分配 空間
  • 設置對象的引用

但是分配就有不少的細節(jié)。為了能進一步提速分配,并不是所有的對象都在 Eden區(qū)來分內存的。

你想啊,整個堆都是線程共享的,如果大家都在這里分內存,就免不了加鎖的操作。為此, JVM 又提供了一個加速選項。在 Eden 里給線程分配自己的私有分配區(qū)域,也就是傳說中的「TLAB(Thread Local Allocation Buffers) 」。這樣每個線程分配的時候,因為是線程私有,就不再需要加鎖,可以快速搞定。分配失敗就會再嘗試加鎖在 Eden 中進行空間分配。

有沒有感覺 TLAB的分配和動物占領領地類似,把某塊區(qū)域拉上便便或者撒上尿,以此提醒其他的動物,這個地方被占領了。 :-)

生活中的例子,有點類似計次的VIP通道。比如你在某個理發(fā)館充值辦了VIP,夠10次剪發(fā)。那這10次之內去的時候,都不需要和其他人一起排隊等,直接分配固定的師傅。那如果還有一次的時候,你是去燙頭,原有的VIP不夠用了,就需要在「燙頭」的資源里去排隊。

在「虛擬機設計與實現」一書中,對于線程局部分配是這樣描述的:

跳增指針分配只可用于空閑空間屬于單個線程的情況。如果有多個線程,那分配應用是線程安全的。為每個對象分配使用原子指令代價過去昂貴。一個常見的解決方案是只對塊分配使用原子操作。每個線程從全局空間空間中用原子指令抓取一個空閑塊,然后在塊中用跳增指針進行對象分配,不用原子操作,這個塊是線程局部用于分配的。

TLAB 該設置多大合適呢?

畢竟分配這個塊也還是需要原子操作的。如果太小,就需要頻繁的去請求塊的分配,從而讓線程局部塊的優(yōu)勢打了折扣。

但塊也不能太大,否則如果應用程序中有很多線程,有些線程可能并不活躍分配對象,就會浪費其中只有少數幾個對象的塊空間。

TLAB的大小 在 HotSpot 中默認是自動調整的,根據線程數以及每次創(chuàng)建對象的大小等一系列來自動評估。

當然,你也應該想到,如果你的對象空間占用大怎么辦?

所以,在進行TLAB分配的時候會判斷現有的余量是否夠分配對象。如果夠還好,直接分配,如果不夠的話,看余下有多少,如果余下的大于允許浪費的量,則會直接在Eden上分配,不走TLAB,否則的話,再申請一塊TLAB,繼續(xù)分配。

對象大小怎么計算呢? 之前有一篇文章《怎樣計算一個 Java 對象大小?這兒有幾種方法~

這種TLAB的分配形式,也被稱為「跳增指針分配」,也就是說分配一個對象的時候,只需要在空閑空間中移動指針,跳增對象大小。

如果TLAB分配失敗就只能在 Eden中不停的重試去分配空間。

分配空間之后, 虛擬機會根據配置,確定是否要對實例數據進行填0操作。這樣后面 Java 代碼里可以不初始賦值就能直接使用了。

再進行對象頭的初始化操作 更新棧頂對象引用

慢速分配則需要在分配實例前,對類進行解析,確保類和依賴的類已經都進行了解析和初始化。

  • 首先需要對類檢查,確保不是抽象類和接口;
  • 然后確保類已經初始化,計算對象大小,在堆上創(chuàng)建實例
  • 最后設置線程棧中的對象引用

怎么樣? 代碼里找個對象也不是那么容易吧 :-)

【本文為51CTO專欄作者“侯樹成”的原創(chuàng)稿件,轉載請通過作者微信公眾號『Tomcat那些事兒』獲取授權】

戳這里,看該作者更多好文

 

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2020-10-16 12:30:58

AI對象軟件

2018-10-24 11:29:55

科技大佬硅谷老婆

2016-12-22 10:44:30

數據分析找對象大數據

2020-12-14 09:46:12

VS Code代碼編程

2021-03-19 13:00:39

樹莓派Linux

2015-11-06 10:07:31

SDN網絡技能

2018-05-28 21:38:10

程序員住房女程序員

2018-08-14 15:38:26

安卓.so文件APK

2011-03-08 16:57:13

proftpd

2013-04-01 14:40:34

App內購家長蘋果

2018-11-15 09:03:13

2009-07-01 09:17:36

對象比較Java

2024-01-29 00:57:20

GuavaJava拷貝

2025-04-11 08:42:10

Java對象TLAB

2021-11-07 14:38:11

攝像頭個人信息

2020-03-04 10:13:55

Kubernetes容器開發(fā)

2020-04-17 14:25:22

Kubernetes應用程序軟件開發(fā)

2013-12-10 10:27:04

密碼

2011-01-19 09:43:24

UbuntuThunderbird
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区二区在线 | 国产精品高潮呻吟久久 | 欧美极品在线观看 | 欧美激情在线一区二区三区 | 在线视频91 | 国产精品揄拍一区二区久久国内亚洲精 | 婷婷综合色 | 国产精品三级久久久久久电影 | 成人自拍av | 人人天天操 | 欧美日在线| 亚洲久久 | 日本在线免费看最新的电影 | 精品国产一级片 | 久久人| 亚洲国产高清在线观看 | 91成人在线 | 日韩欧美三区 | www.xxxx欧美| 日韩精品 电影一区 亚洲 | 亚洲天堂一区 | 日韩视频在线免费观看 | 成人在线精品 | 久久久久国产一区二区三区四区 | 亚洲精品视频导航 | 日日综合| 在线观看国产视频 | 亚洲精品无 | 精品一区二区三区中文字幕 | 色在线看| 亚洲热在线视频 | 国产亚洲一区二区在线观看 | 日本精品一区二区 | www视频在线观看 | 国产91丝袜在线播放 | 色约约视频 | 四虎永久免费黄色影片 | 亚洲一区二区国产 | 国产日产精品一区二区三区四区 | 成人免费视频网站在线看 | 美女福利视频 |