1. 程式人生 > 其它 >深入理解Java虛擬機器-第三版-第二章前的思考

深入理解Java虛擬機器-第三版-第二章前的思考

  第二章的內容主要是JVM的記憶體管理。先不細看這部分內容,這裡先寫下對於一些問題的思考,以便更好地理解後續內容。

  在剛開始接觸Java的時候,也曾經看過JVM相關的內容。但是那個時候讀到各種文章,一上來就會看到那張經典的JVM內部結構圖。而在各種面試中,這些內容也是會被反覆問到。當時只是覺得這個東西太重要了,要想在這條路走下去是必學的,但是裡面的具體內容看得真是一頭霧水。

  現在,已經知道JVM之所以重要,是因為它解決了不同平臺的資源適配(跨平臺),簡化了甚至弱化了開發人員在記憶體管理的很多麻煩,基本把Coder遮蔽在了外面。那麼我們想象一下,如果是讓我們來管理記憶體,會怎麼去著手這個問題呢?

我們來看一些,雖然簡單,但對於我們理解JVM有幫助的一些常識。  

JVM也是一個軟體、也需要和其他軟體共享計算機的記憶體。
我們所有Java執行中所處理的物件或者演算法都使用JVM的記憶體空間
Java 也可以通過一些引數去控制JVM記憶體的使用量。如:最小記憶體 XMS、最大記憶體 XMx
按照正常理解,JVM用於建立物件,隨著物件數量的增加,JVM使用率也在增加。如果JVM使用率達到100%就無法使用,為了讓JVM可以讓更多的物件重複使用,我們需要垃圾回收。
垃圾:不會被使用的物件。
所以JVM中的空間是被迴圈使用的
為了提高垃圾回收的效率,JVM將記憶體區域進行了劃分

  所以,要慢慢理解這個JVM的內部構造為什麼會是這個樣子,我們需要找到一種解釋,就是它為了高效地解決問題,何以不得不成為現在的樣子。

  首先,JVM中是可以啟動多個執行緒的,也就是說,這些執行緒有各自的私人領地,也會有很多公共資源供這些執行緒共同使用,這一點是很好理解的。所以為了遮蔽各個執行緒之間的影響,JVM把記憶體劃分為了棧記憶體和堆記憶體。

  棧記憶體就是給各個執行緒使用的,而堆記憶體是大家一起使用的公共領地。一個JVM中,我們可以啟動多個執行緒,如果說執行緒的數量多了,那麼棧記憶體所使用的的資源肯定會增多的,所以從這個角度上來說,也就比較好理解為什麼棧記憶體的大小會比堆記憶體小很多了。線上程的執行過程中,我們知道如果是單核CPU,那麼執行緒的執行肯定是輪流來執行,那麼不同的執行緒執行到哪一句了,這個資訊JVM肯定是必須要管理的,所以這就是執行緒中的程式計數器的作用。而線上程中(包含主執行緒)執行的方法,在這裡被方法棧進行管理,具體如何管理可以細看書裡的描述,另外JVM單獨使用了本地方法棧來處理native定義的方法,這些方法是JVM通過JNI來呼叫其它語言所實現的方法,所以比較特殊,需要單獨管理。這樣一來,我們就梳理清楚了執行緒中的程式計數器,本地方法棧,方法棧三塊內容。

  堆記憶體中,主要關注的是,就這麼一塊區域,JVM是如何做到能讓我們的程式碼不斷地去new新的物件,保持程式長時間穩定執行的,它是怎麼管理、歸類這些物件,從而提高了記憶體使用的效率?對我們寫程式碼又有哪些啟發,更好地寫出高效程式碼?有了這些疑問,對於新生代、老年代...概念也就有了些感性地理解,只需要知道這些概念以及所出現的管理邏輯都是JVM為了更高效地去管理堆記憶體出現的就好。

  剩下還有比較重要的是方法區,裡面還有常量池,為什麼會這麼設計,為什麼要把類資訊,各種常量等等都放入這個區域?把這些不可變的內容放入這個區域,是為了讓執行緒、堆記憶體中所有的內容都保證為可變的,以便於在物件回收和執行緒資源回收時降低處理的複雜度嗎?

  另外,這幾個區域就是JVM的全部嗎?

  

  帶著這些問題,和自己想到的可能的解釋,再次進入深入理解JVM,我覺得應該能夠收穫的更多。這一篇內容是我在查閱了一些資料基礎上,進行了一些猜測,主要目的就是要在進入JVM細節之前,自己在腦海中構建一套與JVM大體結構相同的框架下,試圖去理解設計者的意圖。在此基礎上,再次檢視相關內容,我覺得更能夠抓住重點,有的放矢。希望也能對看到這篇文章的初學者有所幫助。

  【參考】

  https://www.cnblogs.com/sunweiye/p/10852540.html