JVM中對象模型及相應名詞概念

JVM中對象模型及相應名詞概念

java對象在jvm中的模型是OOP-Klass 模型;java

klass

klass對應元數據,包括常量池、字段、方法等。是在加載class階段建立instanceKlass。存放在方法區。數組

oop

oop對應java中的實例。
oop是指向oopDesc的指針。jvm

// share/vm/oops/oopsHierarchy.hpp
typedef class oopDesc*                            oop; // SimonNote: oop是指向oopDesc的指針

oopDesc

instanceOOpDesc只包含數據信息,主要由如下部分組成:oop

  1. 對象頭,也叫markword。主要存儲對象運行時記錄信息,如hashcode,GC分代年齡,鎖狀態標誌,線程id,時間戳等
  2. 元數據指針,這裏指指向方法區的instanceKlass實例
  3. 實例數據,(個人理解 對其獲取與存取的方式是按對象頭爲基址作相對偏移後操做的,能夠參見oop.inline.hpp的obj_field_addr方法)
  4. 若是是數組對象,還多一個數組長度

oopDesc的結構圖示:

先是頭部,頭部後面接着數據,數據後面接着對其填充;頭部包含mark和元數。post

oop是普通對象指針之意,對象指針好理解,可是最前面那個o是普通的意思,怎麼理解這個普通?參見R大解釋google

爲何把GC託管指針叫作oop?對象指針不就是指針麼,爲啥還要加一個「普通」來修飾?
這有個有趣的歷史緣由。對Smalltalk與HotSpot VM的淵源有所瞭解的話就會知道。在Strongtalk VM的文檔裏有詳細描述:https://code.google.com/p/strongtalk/wiki/VMTypesForSmalltalkObjects
關鍵點在於在Smalltalk的對象由GC來管理,而其許多實現裏都會用所謂「直接對象」的方式來實現一些簡單的值類型對象,例如SmallInteger。所謂「直接對象」(immediate object)就是並不在GC堆上分配對象實例,而是直接將實例內容存在對象指針裏的對象。這樣的指針也叫作「帶標記的指針」(tagged pointer)。
因而在這種環境中,每當咱們拿到一個對象指針時,都得先問它:你是一個直接對象仍是一個真的指針?若是是真的指針,它就是一個「普通」的對象指針了。這樣對象指針就有了「普通」與「不普通」之分。
這個語境中的oop也被認爲是「object oriented pointer」的縮寫。不管是「ordinary object pointer」仍是「object oriented pointer」,其實要說的事情是如出一轍的。之前術語特別混亂,oop到底最最初是誰的縮寫就不大好考證了。
關於tagged pointer,HLLVM羣組的一個老帖也有討論:http://hllvm.group.iteye.com/group/topic/17840#post-126408spa

之間關係

舉例:
Person示例---- ---> ------- Person的instanceKlass------- ------- -->---------- ------- Person的class
instanceOopDesc -- ------JDK8在metaspace,JDK6 7 在方法區 --------- ------- JDK7 8 在堆中,JDK6在方法區線程

相關文章
相關標籤/搜索