天天看點

jvm開發筆記5 – 虛拟機記憶體管理

作者:王智通

一、 前言

ajvm是筆者正在開發中的一個java虛拟機, 想通過編寫這個jvm幫助程式員了解jvm的具體實作細節, 它是國内第一個開源的java虛拟機項目:https://github.com/cloudsec/ajvm, 同時筆者把它的開發筆記也分享到了ata上。 在前面4篇筆記中, 已經實作了class檔案加載器, 反彙編器,jvm的crash資訊處理, 同時它已經能運作簡單的java代碼了。 在今天的這篇筆記中, 将開始分享ajvm的記憶體管理子產品是如何編寫的。

二、記憶體配置設定

看下面一段java代碼:

首先用javac編譯下, 然後用ajvm的反彙編器檢視bytecode:

源碼中data = new int[2];對應的彙編指令為:

根據jvm虛拟機規範的描述, newarray指令的作用是, 從操作數堆棧用取出data數組的元素個數,然後根據newarray後面的type進行計算要申請的記憶體大小, type的值在虛拟機規範中如下:

是以10代表這個int類型的數組, 接下來就要給data這個數組從heap中配置設定記憶體了。

ajvm的記憶體堆用的是slab算法, slab的記憶體結構如下:

源碼中的slab.c是它完整的實作, 不熟悉slab的同學請自行google。

三、垃圾回收

gc是java程式員普遍關心的問題, 當記憶體不夠時, 将會觸發jvm的垃圾回收機制。

ajvm使用最原始的引用計數法, 需要建立一個新的資料結構:

當數組申請完記憶體後, 将會建立一個新的jvm_object與其對應, ref_count被初始化為0, addr指向數組的首位址, size表示數組的大小, jvm_object将會被加入到jvm_obj_list_head連結清單中, 在這将來的垃圾回收時将會用到。

當數組被引用時, 我們跟數組的位址在jvm_object連結清單中找到它, 并且把ref_count加1, 表示這個數組在被引用。 比如上面的:

這條指令就會對data數組進行引用, 我們隻要在iastore的解釋代碼裡, 對data對應的ref_count加1即可:

對于數組data1, 同樣進行了記憶體配置設定, 但是始終沒有被引用到, 是以data1将會是gc回收時要釋放的對象。

這是ajvm最簡單的gc算法了, 後續将會對其進行優化。

四、示範執行

下面是ajvm對上述java代碼的解釋和執行過程: