日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java 虚拟机原理】栈帧 | 动态链接 | 方法区 | 字节码文件二进制分析

發(fā)布時間:2025/6/17 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java 虚拟机原理】栈帧 | 动态链接 | 方法区 | 字节码文件二进制分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 一、方法區(qū)
  • 二、字節(jié)碼二進制文件分析
  • 三、動態(tài)鏈接
    • 1、動態(tài)鏈接簡介
    • 2、靜態(tài)鏈接與動態(tài)鏈接
    • 3、早期綁定 和 晚期綁定
    • 4、動態(tài)鏈接示例

前言

" 棧幀 " 中存儲的是 局部變量表 , 操作數(shù)棧 , 動態(tài)鏈接 , 方法出口 ;





一、方法區(qū)



字節(jié)碼文件加載到內存中后 , 該文件的 Class 會存放到 方法區(qū) ( 元空間 ) 中 ; 方法區(qū) 中存儲 靜態(tài)變量 , 常量 , 類元信息 ;

類元信息 是由 方法和數(shù)據(jù)組成 ;


如果定義了一個靜態(tài)變量類對象 , 那么方法區(qū)中 , 的該靜態(tài)變量 指向了 堆 中的對象 ;

public static HelloWorld mHelloWorld = new HelloWorld();

如果在 方法的局部變量 中創(chuàng)建了 類對象 , 那么 線程棧 中的局部變量 , 也會指向 堆 中的對象 ;

public static void main(String[] args) {HelloWorld helloWorld = new HelloWorld();helloWorld.add();}

類 的 實例對象 創(chuàng)建完成后 , 除了在類中封裝的成員之外 , 還包括 " 對象頭 " ( Object Header ) ,

對象頭 中包含 333 部分內容 :

  • 數(shù)據(jù)區(qū) ;
  • Marker Word 表及字段 ;
  • KlassPointer 類型指針 , 指向 方法區(qū) ( 元空間 ) 中的 類元信息 的地址 ;





二、字節(jié)碼二進制文件分析



Java 源代碼如下 :

public class HelloWorld {public static HelloWorld mHelloWorld = new HelloWorld();public int add() {int a = 1;int b = 1;int c = a + b;return c;}public static void main(String[] args) {HelloWorld helloWorld = new HelloWorld();helloWorld.add();} }

字節(jié)碼文件二進制數(shù)據(jù)分析 :

使用二進制查看工具查看 HelloWorld.class 字節(jié)碼文件 , 這些二進制數(shù)值對應的就是 JVM 指令 ;

執(zhí)行

javap -v HelloWorld.class

命令 , 命令行終端輸出的就是字節(jié)碼二進制數(shù)據(jù)的翻譯內容 ;

major version: 52 配置 JDK 版本 ;

Constant pool 常量池 ;

D:\java>javap -v HelloWorld.class Classfile /D:/java/HelloWorld.classLast modified 2021-9-2; size 373 bytesMD5 checksum a9899195af11ef123968f811f4aa71f4Compiled from "HelloWorld.java" public class HelloWorldminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER Constant pool:#1 = Methodref #5.#16 // java/lang/Object."<init>":()V#2 = Class #17 // HelloWorld#3 = Methodref #2.#16 // HelloWorld."<init>":()V#4 = Methodref #2.#18 // HelloWorld.add:()I#5 = Class #19 // java/lang/Object#6 = Utf8 <init>#7 = Utf8 ()V#8 = Utf8 Code#9 = Utf8 LineNumberTable#10 = Utf8 add#11 = Utf8 ()I#12 = Utf8 main#13 = Utf8 ([Ljava/lang/String;)V#14 = Utf8 SourceFile#15 = Utf8 HelloWorld.java#16 = NameAndType #6:#7 // "<init>":()V#17 = Utf8 HelloWorld#18 = NameAndType #10:#11 // add:()I#19 = Utf8 java/lang/Object {public HelloWorld();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0public int add();descriptor: ()Iflags: ACC_PUBLICCode:stack=2, locals=4, args_size=10: iconst_11: istore_12: iconst_13: istore_24: iload_15: iload_26: iadd7: istore_38: iload_39: ireturnLineNumberTable:line 4: 0line 5: 2line 6: 4line 7: 8public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=2, args_size=10: new #2 // class HelloWorld3: dup4: invokespecial #3 // Method "<init>":()V7: astore_18: aload_19: invokevirtual #4 // Method add:()I12: pop13: returnLineNumberTable:line 11: 0line 12: 8line 13: 13 } SourceFile: "HelloWorld.java"





三、動態(tài)鏈接




1、動態(tài)鏈接簡介


動態(tài)鏈接 又稱為 運行時常量池方法引用 ;

每個 方法 都有一個對應的 " 棧幀 " , 在棧幀 內部 的 " 動態(tài)鏈接 " 中 , 包含了 " 運行時常量池 " 中 棧幀對應方法的引用 , 該操作的目的是支持當前 方法實現(xiàn) 動態(tài)鏈接 ;


2、靜態(tài)鏈接與動態(tài)鏈接


靜態(tài)鏈接 : 字節(jié)碼文件加載到 Java 虛擬機內存后 , 如果在 編譯階段 就知道 目標方法 的 引用 , 并且在 運行時引用不變 , 那么調用方法時 , 直接使用 方法的符號引用 轉為 直接引用 的過程 , 稱為 靜態(tài)鏈接 ;

動態(tài)鏈接 : 編譯階段 , 無法確定 被調用的方法 , 只能在 運行時方法符號引用 轉為 直接引用 , 這種 動態(tài)的引用轉換 , 稱為 動態(tài)鏈接 ;


3、早期綁定 和 晚期綁定


方法綁定 分為 早期綁定 和 晚期綁定 ;

早期綁定 : 被調用的方法在 編譯期 可以知道 , 并且運行時保持不變 , 靜態(tài)鏈接 ;

晚期綁定 : 被調用的方法 在 編譯期 無法確定 , 在運行時動態(tài)地綁定相關方法 , 動態(tài)鏈接 ;


4、動態(tài)鏈接示例


動態(tài)鏈接指的是 , 將 Java 源碼編譯為 class 字節(jié)碼文件后 , 方法調用 如 helloWorld.add() , 在 class 字節(jié)碼文件中只是一個字符 , 在運行時 , 需要靠 " 動態(tài)鏈接 " 指向要運行的 helloWorld.add() 方法首地址 ;

" 動態(tài)鏈接 " 本質是 將 " 符號引用 " 轉為 " 直接引用 " ;


在上述字節(jié)碼 常量池 中 HelloWorld 類的 add 方法的引用如下 :

#4 = Methodref #2.#18 // HelloWorld.add:()I

#4 = Methodref 指向了 #2.#18 , #18 就是 add 方法 ;

#18 = NameAndType #10:#11 // add:()I

總結

以上是生活随笔為你收集整理的【Java 虚拟机原理】栈帧 | 动态链接 | 方法区 | 字节码文件二进制分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。