對于從事 C/C++ 程式員開發的小夥伴來說,在記憶體管理領域非常頭疼,因為他們總是需要對每一個
new
操作去寫配對的
delete/free
代碼。而對于我們 Android 乃至 Java 程式員,卻總是會因為虛拟機的自動記憶體管理機制而忽視記憶體管理的重要性。
經過前面簡短的幾篇純 Android 問題,我想再給大家摻雜一點可能平時你并沒有太多關注的東西。其實寫這個的時候我相當糾結,因為對于大多數 Android 開發來說,他們會更加注重實質性的技能提升,而不是我今天将要講的 Java 虛拟機結構。
但經過一系列的思想鬥争,我還是打算把這個講到底,為了不浪費大家太多的時間,我依然遵從「每日一問」系列的初衷,我們盡可能地精簡文字,讓每一個小知識點閱讀時間都控制在 5 分鐘以下。
Java 虛拟機結構作為一個面試高頻考點,你完全可以當做你在複習面試知識,這樣興許你的學習的心态會好一些。
我還是不得不去網上摘下了這個圖,我想唯有用這張圖結合講解起來才更加的通俗易懂。
Java 虛拟機記憶體區域确實就由這幾部分構成:方法區、虛拟機棧、本地方法棧、堆、程式計數器。
程式計數器
程式計數器是一個較小的記憶體空間,線程私有,它是唯一一個在 Java 虛拟機規範中沒有規定任何 OOM 情況的區域。
虛拟機棧
虛拟機棧和程式計數器一樣,同樣為線程所私有,并且生命周期和線程相同。。每個棧中的資料都是私有的,其他棧不允許通路,每個方法被執行的時候都會同時建立一個棧幀,每一個方法被調用直至執行完成的過程,就對應着一個棧幀在虛拟機棧從入棧到出棧的過程。虛拟機棧主要存放各種編譯期可知的基本資料類型和對象的引用。
本地方法棧
本地方法棧與虛拟機棧發揮的作用非常相似,其主要差別是虛拟機棧為虛拟機執行 Java 方法(也就是位元組碼)服務,而本地房發展則是為虛拟機用到的 Native 方法服務。
Java 堆
Java 堆是垃圾收集器管理的主要區域,主要用于存放對象的執行個體,自然而然就成了 Java 虛拟機中管理記憶體最大的一塊,并且它可以處于實體上不連續的記憶體空間中,Java 堆在虛拟機啟動的時候就進行建立,并被所有線程所共享。
方法區
方法區和 Java 堆一樣,是各個線程共享的記憶體區域,主要存儲已被虛拟機加載的類資訊、常量、靜态變量、即時編譯器編譯後的代碼等資料。這個區域的記憶體回收目标主要是針對常量池的回收和對類型的寫在,較少發生垃圾收集行為。
上面對 Java 虛拟機結構進行了非常精簡的講解,大家可還對此清晰了一些?如果還是沒有太透徹其實沒有關系,多回顧幾遍,最好能自己畫一個圖,在一邊進行了解。明天我們再來講一講我們另外一個面試非常高頻的考點:垃圾回收算法,一起來探究 Java 虛拟機到底是怎麼來回收一個無用的對象的。