大資料基礎篇----jvm的知識點歸納-5個區和記憶體回收機制

來源:互聯網
上載者:User

標籤:管理   主線程   複製   method   放棄   定義   應用   新生代   編譯器   

一直對jvm看了又忘,忘了又看的。今天做一個筆記整理存放在這裡。

我們先看一下JVM的記憶體模型圖:

上面有5個區,這5個區幹嘛用的呢?

我們想象一個情境:

我們有一個class檔案,裡面有很多的類的定義是不是,類的定義放在什麼地方呢?類的定義就放在方法區裡面。

程式在運行時會產生很多的對象,比如LinkList等這些對象就存放在堆裡面。

棧:

我們的程式在運行時本質上就是啟動線程在運行,比如main函數就是一個主線程。一個main主線程可以有很多的子線程。

線程在工作就是執行我們的各種方法。方法裡面肯定有我們自己定義了一些局部的變數,比如我們在方法裡面new了一個對象,對象肯定是放在堆裡面的,但是對堆的引用我們就放在棧裡面。那麼棧就有問題了,我們一個程式有很多的線程,如果把所有的線程裡面的變數存放在一起,肯定有會有變數是重複的,衝突。所有不能放在一起。所以棧裡面是分線程來存放的。每一個線程都是自己的棧空間,線程私人的。堆是線程共用的。     

棧裡面有一個細節:

就是說一個棧空間是以不同的線程區分開來。每個線程有自己棧,每個線程裡面又會執行很多的方法,每一個方法對應一個棧幀:

每個方法執行時都會建立一個棧幀(Stack Frame)用語儲存局部變數表、運算元棧、動態連結、方法出口等資訊。從從可以看到,每個線程在執行一個方法時,都意味著有一個棧幀在當前線程對應的棧幀中入棧和出棧。

圖中可以看到每一個棧幀中都有局部變數表。局部變數表存放了編譯期間的各種基礎資料型別 (Elementary Data Type),對象引用等資訊。

 

好了,我們看一下具體的東西:

本地方法棧(Native Stack

         本地方法棧(Native Stack)與Java虛擬機器站(Java Stack)所發揮的作用非常相似,他們之間的區別在於虛擬機器棧為虛擬機器棧執行java方法(也就是位元組碼)服務,而本地方法棧則為使用到Native方法服務。

 

 堆(Heap

         對於大多數應用來說,Java Heap是Java虛擬機器管理的記憶體的最大一塊,這塊地區隨著虛擬機器的啟動而建立。在實際的運用中,我們建立的對象和數組就是存放在堆裡面。如果你聽說安全執行緒的問題,就會很明確的知道Java Heap是一塊共用的地區,操作共用地區的成員就有了鎖和同步。在程式的運行中不斷地new 對象,就存在堆裡面。

         與Java Heap相關的還有Java的記憶體回收機制(GC),Java Heap是記憶體回收行程管理的主要區域。程式猿所熟悉的新生代、老生代、永久代的概念就是在堆裡面,現在大多數的GC基本都採用了分代收集演算法。如果再細緻一點,Java Heap還有Eden空間,From Survivor空間,To Survivor空間等。

         Java Heap可以處於物理上不連續的記憶體空間中,只要邏輯上是連續的即可。

 

上面這張圖就是我們新生代,老年代的圖。涉及到記憶體回收機制。

我們來介紹一下記憶體回收機制:

剛開始時建立的對象都存放在Eden Sapce裡面(伊甸園,新生代),大家都無憂無慮的。然後呢 ,記憶體回收機制來了。先對生活在伊甸園的對象檢測一次,發現還有利用價值就把對象放在Survivor空間裡面的From Space,survivior空間分為兩塊,一塊是From Space,一塊是ToSapce空間。ToSpace空間是很少用的(就是用來做記憶體回收的挪動的)。然後記憶體回收機制對From Space的對象回收比如18次,還能倖存下來,就放在老年代裡面(Old Generation)。我們很奇怪,這裡的ToSpace是幹嘛用的。

好了我們來介紹下記憶體回收演算法:

有 兩種演算法。

1:對象A有沒有引用對象B.有引用就不是垃圾,這種方法有問題。A,B相互引用,就不能區分出是不是垃圾了。

2:根節點搜尋。從根節點往下搜尋。能搜尋到了就不是垃圾,不能搜尋到的,就是垃圾。

 

 

 這是由映射表記錄的,再詳細就不知道了。

 

 

對象其實就是一個方格:

如上,紅色是好的對象,黑色的是垃圾對象。

我們怎麼去回收黑色的對象呢:

方法一:標誌-清除:

直接把黑色的對象清除掉。

 

但是有一個問題:這樣清除掉的惡化,我的空間變得很零散。下次要放一個大的對象的話(必須是一個連續的空間)比如四個格子,就放不下去了。

 

方法二:標記整理:

 

 我只移動有用的:把紅色的有用的對象移動到白色的空白地方。但是造成的問題是:對在啟動並執行程式有影響。

 

方法三:

複製演算法:

預先存留一塊有用的的空間:那就是上文提到的ToSpace空間。

 

 在FromSpace空間中,記憶體回收機制把沒用的的對象標記成黑色的,然後把紅色的有用的對象都轉移到右邊的ToSpace空間,等到記憶體回收機制把左邊的黑色和紅色全部清除之後。再把右邊的ToSpace的那些紅色有用對象再移植到左邊的FromSpace空間。這樣就整齊了。

然後我們會想一個問題。那右邊給他預留這麼大的空間不是很浪費嗎?其實實際上右邊的空間不需要那麼大,只要一點點就夠了。如

 

因為我們的有用的對象(紅色的方塊)其實是很少的。很多個物件用好一次就不用了的。

 

  方法區(Method Area

         方法區(Method Area)與堆(Java Heap)一樣,是各個線程共用的記憶體地區,它用於儲存虛擬機器載入的類資訊,常量,靜態變數,即時編譯器編譯後的代碼等資料。雖然Java虛擬機器規範把方法區描述為堆的一個邏輯部分,但是她卻有一個別名叫做非堆(Non-Heap)。分析下Java虛擬機器規範,之所以把方法區描述為堆的一個邏輯部分,應該覺得她們都是儲存資料的角度出發的。一個儲存物件資料(堆),一個儲存靜態資訊(方法區)。

         在上文中,我們看到堆中有新生代、老生代、永久代的描述。為什麼我們將新生代、老生代、永久代三個概念一起說,那是因為HotSpot虛擬機器的設計團隊選擇把GC分代收集擴充至方法區,或者說使用永久代來實現方法區而已。這樣HotSpot的垃圾收集器就能想管理Java堆一樣管理這部分記憶體。簡單點說就是HotSpot虛擬機器中記憶體模型的分代,其中新生代和老生代在堆中,永久代使用方法區實現。根據官方發布的路線圖資訊,現在也有放棄永久代並逐步採用Native Memory來實現方法區的規劃,在JDK1.7的HotSpot中,已經把原本放在永久代的字串常量池移出。

大資料基礎篇----jvm的知識點歸納-5個區和記憶體回收機制

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.