java對象在jvm中的模型是OOP-Klass 模型;java
klass對應元數據,包括常量池、字段、方法等。是在加載class階段建立instanceKlass。存放在方法區。數組
oop對應java中的實例。
oop是指向oopDesc的指針。jvm
// share/vm/oops/oopsHierarchy.hpp typedef class oopDesc* oop; // SimonNote: oop是指向oopDesc的指針
instanceOOpDesc只包含數據信息,主要由如下部分組成:oop
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在方法區線程