Java 內存——Java虛擬機中對象的創建、存儲、訪問定位。

轉自:
http://m.blog.csdn.net/blog/kingzma/41097353

Java中,對象的創建與銷燬無時無刻不在進行之中,但是在虛擬機中,對象的創建是再怎麼樣的?(除開數組,因爲數組直接在堆上分配;除開Class對象,詳情見我的blog,Java中的Class對象。)

JVM中對象的創建過程

當JVM遇到一個new的指令時,首先回去常量池中定位到一個類的符號引用。,並且檢查類的符號引用代表的類是否已經被加載、鏈接、初始化過。如果沒有,則先進行相應的類加載過程。

  當類加載檢查通過後,JVM開始爲對象分配內存。大小在類加載完後已經確定。此時,如何分配內存在這裏可以探討一下。

方法一:指針碰撞,java堆中的內存絕對規整,使用的放在一邊,空閒的放在一邊。他們之間放一個指針做指示器,分配時內存向未使用過的內存偏移。
方式二:空閒列表,已使用和空閒內存交叉,JVM維護一張表,記錄那些內存已經使用。在分配時,從列表中找出一塊足夠大的空間,並跟新記錄。
爲什麼會存在這兩種方式,這是和垃圾回收採用的算法相關的。詳情請參閱我的博文—-Java的垃圾回收機制。

如果你看完覺得分配沒問題了,就大錯特錯了。考慮一下多線程的問題:

當你正在在爲對象A分配一塊內存時,指針還未修改;此時爲對象B也分配到了這塊內存怎麼辦?爲了解決此問題,由於多線程造成的問題。虛擬機採用CAS失敗重試的方法進行保證更新的原子性:另一種方式,每個線程在java堆中都預先分配一小塊內存,哪個線程需要分配內存,就在哪個線程所被分配的內存重分配。當此內存使用完,進行同步鎖定。

JVM中對象的內存佈局

     對象在內存的存儲佈局可以分爲3塊區域:對象頭、實例數據和對齊填充

     對象頭包括兩部分信息:1>.對象運行時自身的數據,比如HashCode、GC分帶年齡等。  2.>類型指針。指向它類元數據的指針。

     實例數據:程序代碼中所定義的各種類型字段的內容。

     對齊填充:佔位符的作用。因爲VM要求對象其實地址必須是8字節的整數倍。

JVM中對象的訪問定位

 Java程序需要通過棧上reference數據來操作對上的具體對象。目前主流的訪問方式有句柄和直接指針。

 直接指針:reference中存放的是對象地址。直接可以訪問。

 句柄(類型兩級指針):Java堆中劃分一塊內存作爲句柄池,reference存放的是對象的句柄地址,而句柄對象中存放了對象實錄數據與數據類型個自己的地址。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章