JVM-浅堆和深堆的区别?
背景
????在閱讀本文之前可先了解一下原來(lái)寫過(guò)的一篇關(guān)于堆的文章:jvm堆
????????java堆內(nèi)存里面存放著各種對(duì)象,而大部分我們的對(duì)象存放于堆中,但堆又分為淺堆和深堆,主要區(qū)別于堆的大小和被GC回收后,可以釋放內(nèi)存的大小。
淺堆(Shallow Head)是什么?
????????淺堆指一個(gè)對(duì)象所消耗的內(nèi)存,當(dāng)在32位系統(tǒng)中,一個(gè)對(duì)象引用會(huì)占據(jù)4個(gè)字節(jié)(32位),比如一個(gè)Int類型的對(duì)象會(huì)占據(jù)4個(gè)字節(jié),而long類型的變量會(huì)占8個(gè)字節(jié),每個(gè)對(duì)象頭都會(huì)占據(jù)8個(gè)字段,由于堆的快照格式不同,對(duì)象的大小可能存在同8字節(jié)進(jìn)行對(duì)齊。(JDK7)
大小計(jì)算:淺堆大小 =?對(duì)象頭 + 實(shí)例數(shù)據(jù) + 對(duì)齊填充
| 對(duì)象類型 | 名稱 | 占用字節(jié) |
| int | hash32 | 4 |
| int | hash | 4 |
| ref | value | 8 |
| head | 對(duì)象頭 | 8 |
| padding | 填充 | 4 |
比如:一個(gè)StrIng 里面有2個(gè)int 共占8個(gè)字節(jié),對(duì)象引用占4個(gè)字節(jié),對(duì)象頭占用8個(gè)字節(jié),填充頭 4個(gè)字段,總共24個(gè)字節(jié),這24就是最終這個(gè)淺堆的大小。
注意這里,淺堆的引用可能引用了非常多的對(duì)象,這里淺堆不需要關(guān)心,僅計(jì)算該引用的大小固定為4,而深堆才關(guān)心具體引用內(nèi)容大小。
深堆(Retained Heap)是什么?
????在了解深堆之前需要先了解一下保留集(Retained Set),指對(duì)象被垃圾回收后,可以被釋放所有對(duì)象的集合,即對(duì)僅能通過(guò)對(duì)象引用到的直接或間接的所有對(duì)象的集合。
個(gè)人理解:比如下面的A、B、C、D、E,其中A引用了 C D 而B 引用了D E,只能通過(guò)A直接或間接引用的用只有C,而只能通過(guò)B直接或間引用只有E,其中D是被共用,所以不被任何一個(gè)對(duì)象占有,所以B不屬于任保一個(gè)保留集。
了解以上的保留集,再來(lái)了解深堆就很簡(jiǎn)單了,深堆指對(duì)象的保留集所有的對(duì)象淺堆大小的總和。
深堆大小:對(duì)象本身+指向的保留集
比如:B的大小是:B+E
對(duì)象實(shí)際大小計(jì)算:淺堆大小+引用的大小
比如:B的實(shí)際在小是 B+ D+ E
注意:以上的淺堆、深堆、對(duì)象實(shí)際大小計(jì)算各不相同;
最后
????淺堆和深堆在面試中,經(jīng)常會(huì)用來(lái)提前面試者,這兩者有什么區(qū)別,有什么關(guān)系,怎么計(jì)算大小等。對(duì)于我們來(lái)說(shuō),除了可能面試會(huì)用上,實(shí)際開發(fā)過(guò)程中,也有很好的學(xué)習(xí)作用,比如太多的引用你會(huì)發(fā)現(xiàn)OOM,這種溢出或者泄露的問(wèn)題排查以及代碼的魯棒性是不是更佳等,以及使用一個(gè)內(nèi)存分析工具經(jīng)常也會(huì)用來(lái)進(jìn)行分析的指標(biāo),比如MAT、jprofiler等。
參考文章:
https://www.imooc.com/article/317274
https://my.oschina.net/aidelingyu/blog/1602341
總結(jié)
以上是生活随笔為你收集整理的JVM-浅堆和深堆的区别?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 突变点检测:Pettitt突变点检测(p
- 下一篇: 2022汽车驾驶员(高级)考试模拟100