1. 程式人生 > >java物件記憶體到底佔用多少

java物件記憶體到底佔用多少

一個Java物件到底佔用多大記憶體

Java物件的記憶體佈局:物件頭(Header),例項資料(Instance Data)和對齊填充(Padding)

物件佔用的記憶體大小還受到VM引數是否開啟指標壓縮UseCompressedOops的影響

記憶體大小:(物件頭 + 例項資料 + 對齊補充padding) % 8等於0 且 0 <= padding < 8

我所在的環境是64位HotSpot虛擬機器,作業系統 64位Windows 7.以下例子均已不開啟指標壓縮,開啟指標壓縮計算方法類似,不再贅述

具體資料型別所佔記憶體

一 物件頭

物件頭在32位系統上佔用8bytes,64位系統上佔用16bytes。

開啟(-XX:+UseCompressedOops)物件頭大小為12bytes(64位機器)。

MemoryCalculation.class類檔案

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
    public static void main(String[] args) {
        System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new MemoryCalculation ())))   
    }
}

編譯執行:
javac MemoryCalculation.java -cp SizeOf.jar MemoryCalculation.java
java -javaagent:sizeOf.jar -XX:-UseCompressedOops MemoryCalculation

輸出結果16.0b(物件頭16 + 例項資料0 + 對齊補充0)

16.0b

二 例項資料

原生型別(primitive type)的記憶體佔用如下:

Primitive Type Memory Required(bytes)
boolean 1
byte 1
short 2
char 2
int 4
float 4
long 8
double 8

reference型別在32位系統上每個佔用4bytes, 在64位系統上每個佔用8bytes。

三 陣列物件

陣列物件的物件頭佔用24個位元組,啟用壓縮之後佔用16個位元組。

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
    public static void main(String[] args) {
        System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new Integer[0]))) 
    }
}

輸出結果24.0b(物件頭24 + 例項資料長度 * 資料長度 + 對齊補充0)

24.0b

複合物件

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
    static class B {
            int a;
            int b;
        }
    static class C {
            int ba;
            B[] as = new B[3];
            C() {
                for (int i = 0; i < as.length; i++) {
                    as[i] = new B();
                }
            }
        }
    public static void main(String[] args) {
        System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new C())));               
    }
}

記憶體圖:

未開啟壓縮:
(16 + 4 + 8 + 4(padding)) + (24+ 8*3) +(16 + 8) * 3 = 152bytes

開啟壓縮:

(12 + 4 + 4 + 4(padding)) + (16 + 4*3 +4(陣列物件padding)) + (12+8+4(B物件padding))*3= 128bytes

再看一個有意思的例子

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
    static class B {
            int a;
            int b;
        }
    static class C {
            int ba;
            B[] as = new B[3];
        }
    public static void main(String[] args) {
        System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new C())))    ;           
    }
}

未開啟壓縮:
(16 + 4 + 8 + 4(padding)) + (24+ 8*3) + 0 = 80 bytes

問:為什麼這裡B物件所佔記憶體為0呢?
答:因為建立物件時,只分配陣列as的引用的記憶體,所指向的物件記憶體還未指定,即資料未初始化,此時所佔記憶體為0,,而前面的例子陣列中所指的物件在建構函式中已初始化.

心得:

  1. 對這個學習主要是讓自己對java記憶體中物件的佈局和所佔大小有個瞭解
  2. 發現物件中方法是不佔用記憶體的

參考連結:

資源下載:

相關推薦

java物件記憶體到底佔用多少

一個Java物件到底佔用多大記憶體 Java物件的記憶體佈局:物件頭(Header),例項資料(Instance Data)和對齊填充(Padding) 物件佔用的記憶體大小還受到VM引數是否開啟指標壓縮UseCompressedOops的影響

java物件記憶體佈局中的基本型別欄位排列順序

java物件記憶體佈局: mark word class物件指標 類欄位 補齊位 如果是陣列物件,2、3之間應該加上  陣列長度 佈局排列表: 32位jdk 普通物件 32位jdk 陣列物件

Ehcache計算Java物件記憶體大小

在EHCache中,可以設定maxBytesLocalHeap、maxBytesLocalOffHeap、maxBytesLocalDisk值,以控制Cache佔用的記憶體、磁碟的大小(注:這裡Off Heap是指Element中的值已被序列化,但是還沒寫入磁碟的狀態,貌似只有企業版的EHCache支援這種配

計算Java物件記憶體大小

摘要 本文以如何計算Java物件佔用記憶體大小為切入點,在討論計算Java物件佔用堆記憶體大小的方法的基礎上,詳細討論了Java物件頭格式並結合JDK原始碼對物件頭中的協議欄位做了介紹,涉及記憶體模型、鎖原理、分代GC、OOP-Klass模型等內容。最後推薦JDK自帶的Hotspot De

Java物件記憶體儲存,引用傳遞,值傳遞詳細圖解

問題: Java在呼叫函式時,物件作為引數傳遞,執行函式後引數物件的值是否發生改變。 正文: 在解決這個問題之前首先得說說Java物件在記憶體中的儲存機制。 我們知道Java資料型別基本分為兩種,一是基本型別,還一種是引用型別。 基本型別: 物件型別

JAVA物件記憶體表示

      java設計者的意圖是想使程式設計師不要去關心物件的記憶體表示,這樣才能使java更容易使用,但我們瞭解一些儲存的細節和原理會有助於我們設計出更合理的程式碼。例類:*  class A{*      private int x;*      private st

Java物件記憶體佈局

注意:本篇部落格,主要參考自《深入理解Java虛擬機器(第二版)》 1、物件在記憶體中儲存的佈局分為三塊 物件頭 儲存物件自身的執行時資料:Mark Word(在32bit和64bit虛擬機器上長度分別為32bit和64bit),包含如下資訊: 物件hashCode 物件GC分代年齡

JAVA物件記憶體逃逸技術

“棧的優勢是,存取速度比堆要快,僅次於暫存器,棧資料可以共享。但缺點是,存在棧中的資料大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本型別的變數(,int, short, long, byt

Synchronized加鎖、鎖升級和java物件記憶體結構

首先了解一下JMM中定義的記憶體操作: 一個執行緒操作資料時候都是從主記憶體(堆記憶體)讀取到自己工作記憶體(執行緒私有的資料區域)中再進行操作。對於硬體記憶體來說,並沒有工作記憶體和主記憶體的區分,這都是java記憶體模型劃分出來的,它只是一種抽象的概念,是一組規則,並不是實際存在的。Java記憶體模型中定

Java 物件記憶體分析

> 一直對堆記憶體和棧記憶體搞不明白,最近看了一個視訊,有了新的瞭解,在這裡給大家分享一下 ### 物件記憶體與引用 #### 物件 好多剛入門學習 Java 的人總是搞不清楚類和物件的關係,在這裡簡要說明一些。 類:顧名思義,一類東西,比如女孩、男孩、人、狗狗,都是類(class),瑩瑩、小明、團團

Java 物件使用後設置為 null 不會減少記憶體佔用

轉載自《碼農每日一題》 問:Java 物件使用後設置為 null 會減少記憶體佔用嗎? 答:不會,設定為 null 只是棧中指向的引用為 null,但是 new 出來的物件還是存在於堆裡面的,按照目前的 GC 演算法,要等 survior1 or survior

Java物件記憶體實際佔用

一、打包和使用方法參考我之前的這篇文章,本文主要是更新了測量的類及方法,實際測試這個方法更準確。 https://www.cnblogs.com/yoyotl/p/8421287.html  二、新的測量類 //package net.sourceforge.sizeof; impor

百度開源分散式id生成器uid-generator原始碼剖析 偽共享(false sharing),併發程式設計無聲的效能殺手 一個Java物件到底佔用多大記憶體? 寫Java也得了解CPU--偽共享

百度uid-generator原始碼 https://github.com/baidu/uid-generator   snowflake演算法 uid-generator是基於Twitter開源的snowflake演算法實現的。 snowflake將long的64位分為了3部分,時間戳、

百度uid-generator原始碼 偽共享(false sharing),併發程式設計無聲的效能殺手 一個Java物件到底佔用多大記憶體? 寫Java也得了解CPU--偽共享

https://github.com/baidu/uid-generator   snowflake演算法 uid-generator是基於Twitter開源的snowflake演算法實現的。 snowflake將long的64位分為了3部分,時間戳、工作機器id和序列號,位數分配如下。

如何檢視Java物件佔用JVM記憶體大小

轉換成位元組型別 之前遇到要檢視快取大小,找了很多方法都不是很合適,從同事那裡得知一個很好、很準確的方法。現分享如下: private List<Map<String,Object>> paramList=new ArrayList<M

Java物件記憶體佔用的空間

本文主要結合lucene中RamUsageEstimator類來談談Java物件在記憶體中佔用的空間大小。 注意這種計算方式適用

一個Java物件到底佔用多大記憶體

在進行 JVM 調優時,我們經常關注 JVM 各個區域大小以及相關引數,從而進行特定的優化,在一次排查記憶體溢位問題時我不禁想到一個問題,一個 Java 物件到底佔用多大記憶體?下面我們就來分析驗證下。 Java 物件記憶體結構 在 JVM 中,Java 物件都是在堆記憶體上分配的,想要分析出 Java

高端面試必備:一個Java物件佔用多大記憶體

這個問題一般會出現在稍微高階一點的 Java 面試環節。要求面試者不僅對 Java 基礎知識熟悉,更重要的是要了解記憶體模型。 #### Java 物件模型 HotSpot JVM 使用名為 oops (Ordinary Object Pointers) 的資料結構來表示物件。這些 oops 等同於本地

JVM記憶體結構、Java記憶體模型以及Java物件模型之間的區別

Java作為一種面向物件的,跨平臺語言,其物件、記憶體等一直是比較難的知識點。而且很多概念的名稱看起來又那麼相似,很多人會傻傻分不清楚。比如本文我們要討論的JVM記憶體結構、Java記憶體模型和Java物件模型,這就是三個截然不同的概念,但是很多人容易弄混。 可以這樣說,很多高階開發甚至都搞

Java 物件記憶體佈局

一個Java 物件在在記憶體中的儲存佈局分為3 塊區域(HostSpot VM): 物件頭(Header) 例項資料(Instance Data) 對齊填充 1. 物件頭 物件頭的資訊主要包括兩個部分: Mark Word 型別指標