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