1. 程式人生 > >JAVA物件記憶體表示

JAVA物件記憶體表示

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

例類:
*  class A{
*      private int x;
*      private static int y;
*      private void f(){...}
*      private void g(int k){...}
*      private static void h(){...}
*  }
*  ...
*  new A();//例項化
      A類中有資料有方法,有靜態的和非靜態的,我們拿該類建立物件,記憶體中的物件將有哪些內容呢?這將涉及到A型別物件佔用多大記憶體。

      我們逐行的來看A類中定義的資料和方法是儲存在記憶體中的什麼位置。
private int x;                          //存放在堆區的A型別物件中
private static int y;                   //存放在靜態資料區
public void f(){...}                    //存放在方法區
private void g(int k){...}              //存放在方法區
private static void h(){...}            //存放在方法區

      在java中有一個專門的記憶體空間是全域性的稱為靜態資料區,用來儲存所有類的靜態資料(該區不包含方法)。
      在java中還有一個專門的記憶體空間叫方法區也是全域性的,所有類的所有方法都存在方法區中,包含普通方法和靜態方法都存在方法區.

      綜合上述我們知道A型別的物件是很小的,在我們這個例子中A型別物件只包含了int x;可見物件並不會佔用很多的記憶體。

      為什麼 static int y;不包含在物件中呢?
      因為y是靜態資料,靜態資料全域性只有一份,一個類只對應一個y變數,將來無論有多少個A的例項y變數都只有一份,既然這樣就沒必要讓y跟隨物件儲存.

      為什麼方法不儲存在物件中呢?

      我們建立了兩個物件可以看出這兩個物件中都有一個int x;這個值可以是不同的,比如一個物件中的可以是5另一個可以是6,但方法就是要執行的程式碼,這個程式碼必然是相同的,不管我們有多少個物件都不能夠改變方法的程式碼,方法的程式碼在整個程式的執行過程中是不變的,既然方法是不變的就沒必要為每個物件都儲存一份方法這樣就太浪費記憶體。

      那麼邏輯上我們可以認為物件是資料加上方法的複合體,可以說資料和方法共同組成了物件,這僅僅是在邏輯上的一種認識 ,真正的儲存我們沒有必要這樣做,只要保證邏輯上的效果就可以了。

下面看一下有繼承情況下物件是如何儲存的。
*  class A{
*      private int x;
*  }
*  class B extends A{
*      private int x;
*      public int y;
*  }
*  class C extends B{
*      private int z;
*  }
      以上C類從B類繼承,B類從A類繼承,A類好像沒有繼承任何類,實際上它是從一個叫作Object的類繼承的,java中任何類都要有一個繼承類
,如果我們不寫預設都是從Object類繼承的。

      那麼在這種情況下我們來建立C型別物件,我們來看C型別物件會包含哪些資料。
      顯然根據前面的分析C型別的物件應該包含C類中所定義的非靜態資料也就是int z;,因為繼承了B類那麼同時也要包含在B類中的非靜態資料,不僅僅包含public的資料也包含private的資料,還要包含祖先類的非靜態資料,所以這裡會產生了兩個int x;,java自己是有辦法區分哪個x屬於哪個類的這裡我們先不管,除了這些還有Object類也有資料,那麼也會包含從Object類繼承來的東西。

      所以各類例項的物件將包含的資料是:
   C類  ->        B類    ->        A類    ->        Object類
   Object資料    Object資料   Object資料
   int x;           int x;           int x;
   int x;           int x;
   int y;            int y;
   int z;

      這裡有一個現象,假如我們只看以上類的繼承的部份資料,我們可以把C類物件當作B型別物件對待或當作A型別的物件看待,由此可見一個物件可以被當作任何它的祖先型別來對待。正是因為這個特點才很方便的支援了多型效果,就如我們知道可以把蘋果當作水果或當作食物來看待一樣,這在邏輯上是非常合理的。

相關推薦

JAVA物件記憶體表示

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

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虛擬機器(第二版)》 1、物件在記憶體中儲存的佈局分為三塊 物件頭 儲存物件自身的執行時資料:Mark Word(在32bit和64bit虛擬機器上長度分別為32bit和64bit),包含如下資訊: 物件hashCode 物件GC分代年齡

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

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

JAVA物件記憶體逃逸技術

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

java字串記憶體表示

      字串是java是最常用的類也是特殊對待的型別之一,字串是定常的無論一個串它儲存在記憶體中的什麼位置它的內容一經建立就不可改變,平時我們感覺到串被修改了這只是一種錯覺 ,實現上串的操作是丟棄了舊串而生成了新串。      java中字面常量表達的串也就是那些用雙引

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

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

Java 物件記憶體分析

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

資料結構(java)---物件記憶體表示

物件在記憶體主要分為二種組成,一個是儲存非靜態的類的屬性物件區,另一個是儲存方法的方法區(包括靜態方法和非靜態方法),如果有靜態常量的話,靜態常量將儲存在靜態常量區中。 因為一個物件例項的屬性是變化的,但是方法和靜態常量是不變,這樣儲存可以更加程度的利用記憶體。 cla

java中double型別的記憶體表示

轉自[http://bbs.csdn.net/topics/260050279] 浮點數儲存的位元組格式如下: 地址 +0 +1 +2 +3 內容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM 這裡 S 代表符號位,1是負,0是正 E 偏移1

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

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

Java 物件記憶體佈局

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

JAVA物件記憶體控制

例項變數與類變數 例項變數 :也叫非靜態變數,在定義該變數時未使用static修飾 類變數: 也叫靜態變數,在定義時使用static修飾 對於static關鍵字而言,表面上他只是靜態的意思,但在java的角度看,它是將例項成員轉化成類成員。他只能修飾在類中定義的成員部分,包括成員變數,方

JVM初窺:Java物件記憶體結構

物件記憶體結構 Class檔案以位元組碼的形式儲存在方法區當中,用來描述一個類本身的記憶體結構。當使用Class檔案新建物件時,物件例項的記憶體結構又究竟是個什麼樣子呢?   如圖所示,為了表示物件的屬性、方法等資訊,HotSpot VM使用物件頭部的一個指標指向Class區域的方式來

java建立物件記憶體分配空間及其原理一

          一直想寫關於java物件的文章,一直拖著就等到了現在。其實,當你真正走上程式設計師這條道路的正軌時,程式碼對於我們來說,已經不再是問題了。但是,假如我問你原理,你真的能知道其一二嗎?

[Java]Java類和物件記憶體分配詳解

描述 程式碼說明: 一.當Person p1 = new Person();第一次被呼叫時需要做兩件事: 1.先判斷類載入器是否載入過Person類,如果沒有則載入到Person型別到方法區 2.在堆中開闢記憶體空間,在棧中物件名引用(指向)堆的相應記憶體空間 二. p1.name = '皓皓': 將堆中n

jvm學習筆記(3)——java物件記憶體分配和物件的回收(GC)

引言:         之前的文章已經提過,java物件例項是存放在堆上的,至於是在伊甸區、存活區還是老年區,這些都是從物件回收(GC)角度來進行的邏輯劃分。所以我們先說物件的回收(GC),然後再依據GC的策略來說明新的物件具體在哪個區生成。 GC(Garbage C