簡單談談我對JVM內存管理的理解(1)

作爲一個java程序員是幸福的,因爲java程序員不用自己去管理內存。沒有管理過內存的程序員,可能真的想不到管理內存的糾結。我離開學校後的第一份工作就是java語言的開發,並且一直從事java開發的工作,在項目級別,沒有接觸過別的語言,嚴格說來,我也沒有體會過單獨管理內存的糾結。但是我的弟弟是一名c++開發工程師。從他的從業經歷來看,管理內存,有時候確實很痛苦。

不用直接管理內存,很多java程序員也就不關心jvm的內存管理。在我看來,jvm雖然很智能,看充其量只不過是一個用的比較好的軟件,並不能替代一個高級java程序員對內存的理解在實際工作中的作用。

所以,我也看了兩本jvm相關的書籍。一本是《java虛擬機規範》,另一本是《深入理解java虛擬機》。看這兩個東西,純粹屬於個人愛好。在開發中用到的並不多,但是對開發過程中的每一行代碼的運行,卻有了更深的理解。所以,如果你現在以javaCoding爲生,那麼如果有時間,如果精力允許,就抽時間看看這兩本書。

我這篇文章裏,只是簡單說說我對jvm內存管理的理解。

jvm對內存管理,有兩個主要的部分,一部分時內存的分配。一部分是內存的回收。

jvm分配內存空間,有兩種方式,第一種是指針碰撞:這種分配方式,是指將整個內存區域分爲兩個部分,一個爲已經使用的內存,另外一個爲尚未使用的趨於,用一個地址指針來作爲兩個區域的分割點。如果要爲虛擬機分配定額內存,只需要將指針移動即可。另外一種方式稱爲空閒列表模式。即虛擬機維護一個關於內存的空閒列表,用來記錄內存區域內,哪些內存塊是空閒的,當jvm需要給運行的代碼分配內存時,需要在空閒列表中查找內存,並進行分配。

那麼這兩種方式是由誰來決定你的呢?很多人可能不會想到。其實這兩種方式,並不是由虛擬機設計者決定的。而是由虛擬機設計者選擇的內存回收算法決定的。如果內存回收器(GC)具有對內存空間的整理功能,那虛擬機所選擇的內存分配方式大多會是指針碰撞方式,畢竟我認爲,這種分配方式是比較高效的。而如果GC不具備內存整理功能。那麼內存的分配會採用空閒列表的方式。因爲如果gc不對內存進行整理,那麼在jvm運行過程中,內存肯定是不連續的,是塊狀零散分佈的。

說完了內存的總體分配方式,我們就來仔細看看jvm中的內存分類。jvm對內存的管理,並不是胡亂使用,隨機分配的。jvm會將真個內存分爲幾個部分,用來存放不同的內容。在運行過程中,同一個類裏面的不同內容,需要放在不同的區域內來管理。

jvm主要分爲:程序計數器,方法棧,堆,方法區,運行時常量池,直接內存等。下面我們來簡單介紹一下這幾個部分。

程序計數器:這個內存區域,相對來說比較小。只用來存儲一些總體的信息。甚至只是一個線程的指針。用來標記一個線程的執行到的點。只記錄線程的進展情況。這個區域在線程暫停時相當有用,主要用來記錄當線程被停止時系統的運行狀況。屬於線程隔離的區域,是線程安全的。

方法棧:棧主要分爲虛擬機棧和本地方法棧,虛擬機棧用來存儲運行過程中class文件內的方法。而本地方法棧則用來存放運行是調用的本地方法,不是java語言本身定義的方法。用來存儲方法,記錄程序運行時的內容。方法棧內一個方法運行全過程,對應着該方法在在方法棧的生命週期。而方法棧的生命週期,是伴隨程序整個生命週期的。方法棧用來存放該方法的一些屬性,和該方法需要的一些局部變量,運行中間結果等等。屬於線程隔離的區域,是線程安全的。

堆:堆是jvm內的一塊共享的區域,多線程共享區域,這也就表明,該區域不是線程安全的。這塊區域也是gc管理的主要區域。至於gc是如何管理這塊內存區域的。我會在後面的博客中介紹。該區域存儲了運行時的大量數據。並且該區域是可以通過參數配置來調整大小的。在堆內部存放着一塊比較特殊的區域--方法區,這塊內存區域主要用來存儲class文件被加載後的信息。這塊部分通常也被稱作“非堆”。

運行時常量池:在類被加載時,虛擬機會活的一系列的信息,類的版本,字段,方法,接口等等。還有一項比較特殊的信息--常量。常量在jvm運行過程中是被放在運行時常量池內存儲的。運行時常量池,也是jvm設計過程中最自由的區域。直接內存是由於jdk1.4引入了NIO引起的。jvm是允許調用本地方法的。本地方法運行的過程及結果,通常不是由jvm管理的。這樣jvm需要獲取這些(過程和結果)是需要將這些信息複製到jvm內的。尤其是我們寫的代碼運行時需要過的這種結果的時候。而NIO就是用來解決這個問題的。從jdk1.4以後,你可以通過jvm堆中的DiretcByteBuffer來訪問本地方法建立的內存區域。這也是最容易引起OutOfMemorry的地方。因爲如果你將過多的內存分配給jvm,而你又需要通過本地方法佔用內存,就會導致直接內存得不到相對應的內存。從而導致異常。

關於jvm內存的分類,大概就這麼多。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章