当前位置:网站首页>卷起來,突破35歲焦慮,動畫演示CPU記錄函數調用過程
卷起來,突破35歲焦慮,動畫演示CPU記錄函數調用過程
2022-07-05 09:45:00 【hi-dhl】
hi 大家好,我是 DHL。公眾號:ByteCode ,專注分享有趣硬核原創內容,Kotlin、Jetpack、性能優化、系統源碼、算法及數據結構、動畫、大廠面經
全文分為 視頻版 和 文字版,
視頻版:
通過語音和動畫,能够更加直觀的看到,內存記錄方法調用和返回過程。
文字版
我們在寫代碼的時候有沒有思考過 方法如何調用 、 方法執行完之後如何返回 、 內存如何記錄方法調用過程 。而這也是今天這篇文章重點內容。
方法調用和返回過程涉及到了,虛擬機棧、程序計數器、局部變量錶、操作數棧、方法返回地址、動態鏈接等等內容,涉及到知識點很多,同時這些內容也是高頻面試題,所以我將拆分成多篇文章,針對每個知識點去做詳細的分析。而今天這篇文章我們重點去看內存是如何記錄方法調用和返回過程。
虛擬機棧
Java 方法以棧幀的形式,運行在虛擬機棧(Java 棧)中,棧是線程私有的,程序啟動的時候,會創建一個 main 線程,操作系統會為每一個線程分配一段內存,線程創建的時候會創建一個虛擬機棧,虛擬機棧的生命周期和線程一樣,線程結束了,虛擬機棧也銷毀了。
每個 Java 方法,對應一個個棧幀,所以方法開始和結束,都是一個個棧幀入棧和出棧的過程,效果如下圖所示。
棧幀
每個 Java 方法,都是一個個棧幀,每個棧幀包括了:局部變量錶、操作數棧、方法返回地址、動態鏈接、附加信息。
- 局部變量錶: 保存方法參數列錶和方法內的局部變量,按照聲明的順序存儲,它以數組的形式展示,如果是實例方法,索引為 0 是 this 的引用,如下圖所示。
索引(Slot) | 名字(Name) |
---|---|
0 | this |
1 | num |
2 | res |
- 操作數棧: 保存方法執行過程中的臨時結果
- 返回地址: 保存調用該方法的 pc 寄存器的值(即 JVM 指令地址),用於方法結束時,返回調用處,讓調用者方法繼續執行下去
- 動態鏈接: 指向運行時常量池中該棧幀所屬方法的引用,即從常量池中找到目標方法的符號引用,然後轉換為直接引用
附加信息:比如程序 debug 時添加的一些附件信息(不重要,不需要關心,可忽略)
這裏只需要知道它們的作用即可,它們的數據結構、字節碼的含義、執行過程等等,後續的文章我將會針對每個知識點去做詳細的分析。
方法調用過程
先寫一段方法調用的代碼,首先會調用 main()
方法之後調用 fun1()
然後調用 fun2()
,如下圖所示。
現在我們來演示一下 Java 虛擬機執行這些 JVM 指令的過程,首先會調用 main () 方法。
main () 方法
main()
方法執行流程動畫效果如下所示。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ApkZcRTw-1654832156342)(https://img.hi-dhl.com/16541790180176.gif)]
- 執行指令
0: aload_0
,從局部變量錶中,讀取索引為 0 的值,壓入操作數棧中,因為是實例方法,所以索引為 0 的值是 this 的引用
- 執行指令
1: iconst_5
,將常量 5 壓入操作數棧中
- 執行指令
2: invokevirtual #7
,常量 5 和 this 從操作數棧中出棧,然後調用this.fun1(5)
首先從常量池中找到方法 fun1()
的符號引用,然後通過動態鏈接將符號引用轉換成直接引用,之後調用 this.fun1(5)
,將方法 fun1()
作為棧幀壓入虛擬機棧中,跳轉到 fun1()
,繼續往下執行。
如何從常量池中找到目標方法的符號引用,然後轉換成直接引用的過程,將會在後面系列文章中詳細分析
在調用 fun1()
之前,fun1()
的局部變量錶和方法返回地址已經確定好了。
進入方法 fun1 (int num)
方法 fun1(int num)
執行流程動畫效果如下所示。
- 執行指令
0: aload_0
,從局部變量錶中,讀取索引為 0 的值,壓入操作數棧中。因為是實例方法,所以索引為 0 的值是 this 的引用
- 執行指令
1: iload_1
,從局部變量錶中,讀取索引為 1 變量 num 的值,並壓入操作數棧
- 執行指令
2: invokevirtual #13
,num 和 this 從操作數棧中出棧,然後調用this.fun2(num)
首先從常量池中找到方法 fun2()
的符號引用,然後通過動態鏈接將符號引用轉換成直接引用,之後調用 this.fun2(num)
,將方法 fun2()
作為棧幀壓入虛擬機棧中,跳轉到 fun2()
,繼續往下執行,調用 fun2()
之前,fun2()
的局部變量錶和方法返回地址已經確定好了。
進入方法 fun2 (int num)
方法 fun2(int num)
執行流程動畫效果如下所示。
- 執行指令
0: iload_1
,從局部變量錶中,讀取索引為 1 變量 num 的值,並壓入操作數棧中
- 執行指令
1: bipush
,將常量 10 壓入操作數棧中
- 執行指令
3: iadd
,num 和常量 10 從操作數棧中出棧,然後進行相加,將結果壓入操作數棧中
- 執行指令
4: istore_2
,從操作數棧中取出結果,並賦值給局部變量錶中索引為 2 的變量 res2
- 執行指令
5: iload_2
,從局部變量錶中,讀取索引為 2 的變量 res2 的值,並壓入操作數棧中
方法退出過程
每個方法即是一個棧幀,每個棧幀會保存方法返回地址,執行 return
系列指令時,會根據當前棧幀保存的返回地址,返回到調用的比特置,繼續往下執行。因此會分為兩種情况。
异常退出
如果出現了异常且捕獲了該异常,則會從异常錶裏查找 PC 寄存器的地址(JVM 指令地址),返回調用處繼續執行。
正常退出時會做以下件事
- 恢複上一個棧幀局部變量錶、操作數棧
- 如果有返回值,將返回值壓入調用者棧幀的操作數棧,是否有返回值根據
return
JVM 指令:ireturn
:返回值是boolean
、byte
、char
、short
和int
類型lreturn
:返回值是Long
類型freturn
:返回值是Float
類型dreturn
:返回值是Double
類型areturn
:返回值是引用類型return
:返回值類型為void
- 設置調用者棧幀的 JVM 指令地址
- 當前棧幀從虛擬機棧中出棧
這篇文章我們只分析正常退出流程,异常退出和正常退出的流程大致都是一樣的。正常退出流程動畫效果如下所示。
- 方法
fun2
結束時,執行最後一條指令ireturn
,當前棧幀從虛擬機棧中出棧,根據當前棧幀保存的方法返回地址,返回到 fun1 ,恢複 fun1 的局部變量錶、操作數棧,將返回結果res2
保存到調用者(fun1)操作數棧中
- 回到方法
fun1(int num)
,執行指令5: istore_2
,變量res2
從操作數中出棧,賦值給局部變量錶中索引為 2 的變量res1
- 執行指令
6: iload_2
,從局部變量錶中,讀取索引為 2 變量res1
的值,並壓入操作數棧中
- 執行方法 fun1 最後一條指令
7: ireturn
,當前棧幀從虛擬機棧中出棧,根據當前棧幀保存的方法返回地址,返回到 main 方法,恢複 main 方法的局部變量錶、操作數棧,將返回結果res2
保存到調用者(main)操作數棧中
- 最後回到方法
main
中,執行最後一條指令5: pop
,操作數棧中的元素出棧
- 執行最後一條指令
6: return
,至此所有的方法調用結束了,方法所占用的內存,也將返回給系統
每次的方法調用,即是棧幀入棧和出棧的過程,同時也需要占用部分內存,用於保存局部變量錶、操作數棧、方法返回地址、動態鏈接、附加信息等等。
當方法執行完,即棧幀出棧,方法調用所占用的內存,也將返回給系統。
全文到這裏就結束了,感謝你的閱讀,如果有幫助,歡迎 在看
、 點贊
、 收藏
、 分享
給身邊的朋友。
真誠推薦你關注我,公眾號:ByteCode ,持續分享硬核原創內容,Kotlin、Jetpack、性能優化、系統源碼、算法及數據結構、動畫、大廠面經。
近期必讀熱門文章
- 揭秘反射真的很耗時嗎,射 10 萬次耗時多久
- 你知道 Iterable 有多慢嗎?試試它提昇性能
- 揭秘 Kotlin 1.6.20 重磅功能 Context Receivers
- Stack Overflow 上最熱門的 10 個 Kotlin 問題
- Android 12 已來,你的 App 崩潰了嗎?
- Google 宣布廢弃 LiveData.observe 方法
- 影響性能的 Kotlin 代碼(一)
- 揭秘 Kotlin 中的 == 和 ===
最後推薦長期更新和維護的項目
個人博客,將所有文章進行分類,歡迎前去查看 https://hi-dhl.com
KtKit 小巧而實用,用 Kotlin 語言編寫的工具庫,歡迎前去查看 KtKit
計劃建立一個最全、最新的 AndroidX Jetpack 相關組件的實戰項目以及相關組件原理分析文章,正在逐漸增加 Jetpack 新成員,倉庫持續更新,歡迎前去查看 AndroidX-Jetpack-Practice
LeetCode / 劍指 offer / 國內外大廠面試題 / 多線程題解,語言 Java 和 kotlin,包含多種解法、解題思路、時間複雜度、空間複雜度分析
边栏推荐
- 从“化学家”到开发者,从甲骨文到TDengine,我人生的两次重要抉择
- Analysis of eventbus source code
- [listening for an attribute in the array]
- How to choose the right chain management software?
- MySQL does not take effect in sorting string types
- Tdengine already supports the industrial Intel edge insight package
- Oracle combines multiple rows of data into one row of data
- Wechat applet obtains household area information
- Kotlin introductory notes (V) classes and objects, inheritance, constructors
- Alibaba's ten-year test brings you into the world of APP testing
猜你喜欢
Node の MongoDB Driver
An article takes you into the world of cookies, sessions, and tokens
Three-level distribution is becoming more and more popular. How should businesses choose the appropriate three-level distribution system?
Online chain offline integrated chain store e-commerce solution
Principle and performance analysis of lepton lossless compression
The research trend of map based comparative learning (gnn+cl) in the top paper
Idea debugs com intellij. rt.debugger. agent. Captureagent, which makes debugging impossible
SQL learning - case when then else
[ctfhub] Title cookie:hello guest only admin can get flag. (cookie spoofing, authentication, forgery)
Kotlin introductory notes (II) a brief introduction to kotlin functions
随机推荐
Tongweb set gzip
为什么不建议你用 MongoDB 这类产品替代时序数据库?
From "chemist" to developer, from Oracle to tdengine, two important choices in my life
TDengine 离线升级流程
LeetCode 556. Next bigger element III
An article takes you into the world of cookies, sessions, and tokens
Resolve the horizontal (vertical) sliding conflict between viewpager and WebView
Talking about the difference between unittest and pytest
测试老鸟浅谈unittest和pytest的区别
Thermometer based on STM32 single chip microcomputer (with face detection)
【饿了么动态表格】
Officially launched! Tdengine plug-in enters the official website of grafana
SQL learning - case when then else
揭秘百度智能测试在测试自动执行领域实践
Kotlin introductory notes (II) a brief introduction to kotlin functions
The most comprehensive promotion strategy: online and offline promotion methods of E-commerce mall
Mobile heterogeneous computing technology GPU OpenCL programming (Advanced)
LeetCode 31. 下一个排列
Unity SKFramework框架(二十四)、Avatar Controller 第三人称控制
写入速度提升数十倍,TDengine 在拓斯达智能工厂解决方案上的应用