java內存使用——如何計算一個Java對象佔用的字節數

原文地址:點擊打開連接 ,翻譯有出入之處,請以原文爲準html

本文中,咱們討論一個問題:如何計算(或者說,估算)一個Java對象佔用的內存數量?java

一般,咱們談論的堆內存使用的前提是以「通常狀況」爲背景的。不包括下面兩種情形:數組

  1. 某些狀況下,JVM根本就沒有把Object放入堆中。例如:原則上講,一個小的thread-local對象存在於棧中,而不是在堆中。spa

  2. 被Object佔用內存的大小依賴於Object的當前狀態。例如:Object的同步鎖是否生效,或者,Object是否正在被回收。翻譯

咱們先來看看在堆中單個的Object長什麼樣子htm

在堆中,每一個對象由四個域構成(A、B、C 和 D),下面咱們逐個解釋一下:對象

  1. A:對象頭,佔用不多的字節,表述Object當前狀態的信息內存

  2. B:基本類型域佔用的空間(原生域指 int、boolean、short等)get

  3. C:引用類型域佔用的空間(引用類型域指 其餘對象的引用,每一個引用佔用4個字節)同步

  4. D:填充物佔用的空間(後面說明什麼是填充物)

下面咱們對A、B、C 和 D 逐一解釋

A:對象頭

  內存中,每一個對象佔用的總空間不只包含對象內聲明的變量所須要的空間,還包括一些額外信息,好比:對象頭 和 填充物。「對象頭」的做用是用來記錄一個對象的實例名字、ID 和 實例狀態(例如,當前實例是否「可到達」,或者當前鎖的狀態等等)。

在當前的JVM版本中(Hotspot),「對象頭」佔用的字節數以下:

  1. 一個普通對象,佔用8 bytes

  2. 數組,佔用 12 bytes,包含普通對象的 8 bytes + 4 bytes(數組長度)

B:基本類型

boolean、byte 佔用 1 byte,char、short 佔用 2 bytes,int、float 佔用 4 bytes,long、double 佔用 8 bytes

C:引用類型

  每一個引用類型佔用 4 bytes

D:填充物

在Hotspot中,每一個對象佔用的總空間是以8的倍數計算的,對象佔用總空間(對象頭+聲明變量)不足8的倍數時候,自動補齊。而,這些被填充的空間,咱們能夠稱它爲「填充物」。咱們看下具體實例:

  1. 一個空對象(沒有聲明任何變量)佔用 8 bytes -- > 對象頭 佔用 8 bytes

  2. 只聲明瞭一個boolean類型變量的類,佔用 16 bytes --> 對象頭(8 bytes) + boolean (1 bytes) + 填充物(7 bytes)

  3. 聲明瞭8個boolean類型變量的類,佔用 16 bytes --> 對象頭(8 bytes) + boolean (1 bytes) * 8

相關文章
相關標籤/搜索