第6章 方法區(qū) 運行時常量池 類加載器

對象Object
里面有

Object{
  Class class;//所屬的類
  Slot[] slots;//實例變量
}

方法區(qū)

運行時數(shù)據(jù)區(qū)的一塊邏輯區(qū)域惶凝,由多個線程共享。
主要存放從class文件獲取的類信息,類變量也存放在方法區(qū)中抒蚜。
當Java虛擬機第一次使用某個類時,它會搜索類路徑耘戚,找到相應的class文件嗡髓,然后讀取并解析class文件,把相關信息放進方法區(qū)收津。
至于方法區(qū)到底位于何處饿这,是固定大小還是動態(tài)調整,是否參與垃圾回收朋截,以及如何在方法區(qū)內存放類數(shù)據(jù)等蛹稍,Java虛擬機規(guī)范并沒有明確規(guī)定。

我放在ClassLoader里面

ClassLoader

public class MyClassLoader  {
    //依賴Classpath來搜索和讀取class文件
    private Classpath classpath;

  //方法區(qū) key是類的完全限定名
    private Map<String, Class> classInfoMap=new HashMap<>();
  
  
    public Class loadClass(String className){

        Class class = classInfoMap.get(className);

        if (class==null){
            classInfo=  ......
            classInfoMap.put(className,class);
        }
        return class;
    }
}

類的加載大致可以分為3個步驟:

  • 1.找到class文件并把數(shù)據(jù)讀取到內存部服;
byte[] data;
 try {
  data = classpath.readClass(name);
} catch (Exception e) {
   e.printStackTrace();
   throw new RuntimeException("java.lang,ClassNotFoundException");
}
  • 2.解析class文件唆姐,生成虛擬機可以使用的類數(shù)據(jù),并放入方法區(qū)廓八;
    JClass classInfo = defineClass(data);
 private JClass defineClass(byte[] data)  {

        //byte[] -> classFile ->class
        JClass jClass = parseClass(data);
//并把其父類和接口也加載
       jClass.interfaces = resolveInterfaces(jClass.getInterfaceNames());
        jClass.superClass = resolveSuperClass(jClass.getSuperClassName());
//放入方法區(qū)
        classInfoMap.put(jClass.getName(),jClass);
        return jClass;
    }
  • 3.鏈接:驗證和準備
 link(Class class ) {
  verify(class)
  prepare(class)
}
prepare(JClass classInfo) {

//數(shù)實例field ,給每個實例field 編號 set一個slotId,總數(shù)存class
        calcInstanceFieldSlotId(class);
//同上,這次是static Field,在class存一個這個數(shù)量的數(shù)組Object[] staticVars;
        calcStaticFieldSlotId(class);

//給final static的field賦值, 
//這些field的屬性里面有常量池index是初值,
// 按其slotId放入類的staticVars
        allocAndInitStaticVars(class);
    }

類信息

JClass {

///////////////////////////////////////////直接copy來classFile
    @Getter(AccessLevel.NONE)
    private int accessFlags;// uint16 類的訪問標志

    //完全限定名奉芦,具有java/lang/Object的形式
    private  String name;// thisClassName
    private  String superClassName;
    private  String[] interfaceNames;
    private RuntimeConstantPool runtimeConstantPool;//存放運行時常量池指針
    private Field[] fields;
    private Method[] methods;

/////////////////////////////////////////////////////////類加載時加工填充的
    public MyClassLoader classLoader;//加載時保留加載器引用
    public  JClass superClass;
    public  JClass[] interfaces;
    public int instanceSlotCount;
    public int staticSlotCount;
    public   Object[] staticVars;
}

對象

{
   JClass jClass;//所屬的類
    Object[] slots;//實例field的值
}

Field

{
//類成員都有的部分
    protected     int accessFlags ;//classFile復制
    protected    String  name;//classFile復制
    public     String  descriptor;//classFile復制

    protected JClass jClass;//所屬的類

    int constValueIndex ;//classFile得 在屬性里 字段的初始值index

//static是類的staticVars的id  實例field是對象里面slots的id
     private   int slotId          ;//類加載時計算
}

Method

{
//類成員都有的部分
    protected     int accessFlags ;//classFile復制
    protected    String  name;//classFile復制
    public     String  descriptor;//classFile復制

    protected JClass jClass;//所屬的類

//來自Code的屬性
  private int maxStack ;
  private int maxLocals ;
  private   byte[]  code ;
}

運行時常量池

用classFile里的常量池 轉的 index不變 沒有就空著

classFile里的常量池 運行時常量池
數(shù)字(i l f d) 原樣
UTF8
STRING(引用UTF8) 字符串
ClASS(引用UTF8) 類引用(類名,使用類[能拿類加載器])
NAME_AND_TYPE(引用UTF8)
FIELD_REF(引用ClASS,NAME_AND_TYPE) field引用(類引用,名,描述)
METHOD_REF(引用ClASS,NAME_AND_TYPE) method引用(類引用,名,描述)
INTERFACE_METHOD_REF(引用ClASS,NAME_AND_TYPE) method引用(類引用,名,描述)

classFile里的常量池有所屬類的引用 , 每個常量都有對常量池本身的引用

類和對象相關指令

new


class=frame.method.class.runtimeConstantPool(操作數(shù)index);
 newObject={
    class
     slot[class.instanceSlotCount]//instanceSlotCount是類加載時按實例field數(shù)出來的
};
  frame.operandStack.push(newObject);

PutStatic

field=frame.method.class.runtimeConstantsPool[指令操作數(shù)index]
field.class.staticVars[field.slotId]

GetStatic

field=frame.method.class.runtimeConstantsPool[指令操作數(shù)index]
frame.operandStack.push(field.class.staticVars[field.slotId])

Putfield

 stack=frame.operandStack;
 val=stack.pop;
 object=stack.pop;
 field=frame.method.class.runtimeConstantsPool[指令操作數(shù)index];
 object.slot[field.slotId]=val;

Putfield

field=frame.method.class.runtimeConstantsPool[指令操作數(shù)index];
 stack=frame.operandStack;
object=stack.pop;
stack.push(object.slot[field.slotId]);

Instanceof

 class=frame.method.class.runtimeConstantPool(操作數(shù)index);
 stack=frame.operandStack;
 object=stack.pop;
 if(object.class isInstanceOf class){
    stack.push(1);
 }else{
   stack.push(0);
 }

Checkcast

object=stack.pop()
 stack.push(object);
 class=frame.method.class.runtimeConstantPool(操作數(shù)index);
 
 if(!object.class isInstanceOf class){
    throw new ClassCastException();
 }

用于


if (xxx instanceof ClassYYY) {//Instanceof
        yyy = (ClassYYY) xxx;//Checkcast
// use yyy
 }

Ldc

Object constant = frame.method().class().runtimeConstantPool[index]
operandStack.push(constant);

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剧蹂,隨后出現(xiàn)的幾起案子声功,更是在濱河造成了極大的恐慌,老刑警劉巖宠叼,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件先巴,死亡現(xiàn)場離奇詭異,居然都是意外死亡冒冬,警方通過查閱死者的電腦和手機伸蚯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來简烤,“玉大人剂邮,你說我怎么就攤上這事『嵴欤” “怎么了挥萌?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長枉侧。 經(jīng)常有香客問我引瀑,道長,這世上最難降的妖魔是什么榨馁? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任伤疙,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘徒像。我一直安慰自己,他們只是感情好蛙讥,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布锯蛀。 她就那樣靜靜地躺著,像睡著了一般次慢。 火紅的嫁衣襯著肌膚如雪旁涤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天迫像,我揣著相機與錄音劈愚,去河邊找鬼。 笑死闻妓,一個胖子當著我的面吹牛菌羽,可吹牛的內容都是我干的。 我是一名探鬼主播由缆,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼注祖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了均唉?” 一聲冷哼從身側響起是晨,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舔箭,沒想到半個月后罩缴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡层扶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年箫章,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怒医。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡炉抒,死狀恐怖,靈堂內的尸體忽然破棺而出稚叹,到底是詐尸還是另有隱情焰薄,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布扒袖,位于F島的核電站塞茅,受9級特大地震影響,放射性物質發(fā)生泄漏季率。R本人自食惡果不足惜野瘦,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鞭光,春花似錦吏廉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至汹买,卻和暖如春佩伤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晦毙。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工生巡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人见妒。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓孤荣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親徐鹤。 傳聞我的和親對象是個殘疾皇子垃环,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)返敬,斷路器遂庄,智...
    卡卡羅2017閱讀 134,669評論 18 139
  • 字節(jié)碼查看工具:WinHex 前言 Java虛擬機實現(xiàn)語言無關性的基石就是Class文件Java虛擬機提供的語言無...
    zlcook閱讀 7,134評論 4 18
  • 1.流程 創(chuàng)建 HelloWorld.java代碼如下package jvm; /** * @author ...
    RunAlgorithm閱讀 1,348評論 4 6
  • 喜歡上搖滾,不單只是喜歡它那種震撼人心的力量吶喊劲赠,更加喜歡它特有的魅力-簡單涛目,真誠。 作為一名90后凛澎,受益前輩們的...
    天水清波閱讀 704評論 0 0
  • 美國硅谷出了一個吊炸天的科技狂人霹肝,他的名字叫Elon Musk--埃隆·馬斯克。為何說他是科技狂人呢塑煎?那么我們來看...
    岱摯閱讀 565評論 0 1