Java筆記-Java 記憶體地區和GC機制

來源:互聯網
上載者:User

標籤:gc   java   記憶體   地區   

此次主要做一下java記憶體地區和GC機制的知識小結,下面的段落部分摘自網路,部分摘自書籍,具體的連結忘記了,因為這是之前學習的時候做下的筆記。還望原作者多多包涵!

1 Java記憶體回收

Java GCGarbage Collection垃圾收集,記憶體回收)機制,是Java與C++/C的主要區別之一,作為Java開發人員,一般不需要專門編寫記憶體回收和垃圾清理代碼,對記憶體泄露和溢出的問題,也不需要像C程式員那樣戰戰兢兢。這是因為在Java虛擬機器(JVM)中,存在自動記憶體管理和垃圾清掃機制。概括地說,該機制對 JVM(Java Virtual Machine)中的記憶體進行標記,並確定哪些記憶體需要回收,根據一定的回收策略,自動的回收記憶體,永不停息(Nerver Stop)的保證JVM中的記憶體空間,防止出現記憶體泄露和溢出問題。

關於JVM,需要說明一下的是,目前使用最多的Sun公司的JDK中,自從 1999年的JDK1.2開始直至現在仍在廣泛使用的JDK6,其中預設的虛擬機器都是HotSpot。2009年,Oracle收購Sun,加上之前收購 的EBA公司,Oracle擁有3大虛擬機器中的兩個:JRockit和HotSpot。Oracle也表明了想要整合兩大虛擬機器的意圖,但是目前在新發布 的JDK7中,預設的虛擬機器仍然是HotSpot,因此本文中預設介紹的虛擬機器都是HotSpot,相關機制也主要是指HotSpot的GC機制。

Java GC機制主要完成3件事:
(1)確定哪些記憶體需要回收;
(2)確定什麼時候需要執行GC;
(3)如何執行GC。

經過這麼長時間的發展(事實上,在Java語言出現之前,就有 GC機制的存在,如Lisp語言),Java GC機制已經日臻完善,幾乎可以自動的為我們做絕大多數的事情。然而,如果我們從事較大型的應用軟體開發,曾經出現過記憶體最佳化的需求,就必定要研究 Java GC機制。

學習Java GC機制,可以協助我們在日常工作中排查各種記憶體溢出或泄露問題,解決效能瓶頸,達到更高的並發量,寫出更高效的程式。我們將從以下四個方面學習Java GC機制:
(1)記憶體是如何分配的;
(2)如何保證記憶體不被錯誤回收(即:哪些記憶體需要回收);
(3)在什麼情況下執行GC以及執行GC的方式;
(4)如何監控和最佳化GC機制。

2 Java記憶體地區

瞭解Java GC機制,必須先清楚在JVM中記憶體地區的劃分。在Java運行時的資料區裡,由JVM管理的記憶體地區分為幾個模組:

其中:

2.1 程式計數器(Program Counter Register)

程式計數器是一個比較小的記憶體地區,用於指示當前線程所執行的位元組碼執行到了第幾行,可以理解為是當前線程的行號指標。位元組碼解譯器在工作時,會通過改變這個計數器的值來取下一條語句指令。每個程式計數器只用來記錄一個線程的行號,所以它是線程私人(一個線程就有一個程式計數器)的。

如果程式執行的是一個Java方法,則計數器記錄的是正在執行的虛擬機器位元組碼指令地址;如果正在執行的是一個本地(native,由C語言編寫完成)方法,則計數器的值為Undefined,由於程式計數器只是記錄當前指令地址,所以不存在記憶體溢出的情況,因此,程式計數器也是所有JVM記憶體區 域中唯一一個沒有定義OutOfMemoryError的地區。

2.2 虛擬機器棧(JVM Stack)

一個線程的每個方法在執行的同時,都會建立一個棧幀(Statck Frame),棧幀中儲存的有局部變數表、操作棧、動態連結、方法出口等,當方法被調用時,棧幀在JVM棧中入棧,當方法執行完成時,棧幀出棧。

局部變數表中儲存著方法的相關局部變數,包括各種基礎資料型別 (Elementary Data Type),對象的引用,返回地址等。在局部變數表中,只有long和double類型會佔 用2個局部變數空間(Slot,對於32位機器,一個Slot就是32個bit),其它都是1個Slot。需要注意的是,局部變數表是在編譯時間就已經確定好的,方法運行所需要分配的空間在棧幀中是完全確定的,在方法的生命週期內都不會改變。
  
虛擬機器棧中定義了兩種異常,如果線程調用的棧深度大於虛擬機器允許的最大深度,則拋出StatckOverFlowError(棧溢出);不過多數Java虛擬機器都允許動態擴充虛擬機器棧的大小(有少部分是固定長度的),所以線程可以一直申請棧,知道記憶體不足,此時,會拋出OutOfMemoryError(記憶體溢出)。

每個線程對應著一個虛擬機器棧,因此虛擬機器棧也是線程私人的。
  

2.3 本地方法棧(Native Method Statck)

本地方法棧在作用,運行機制,異常類型等方面都與虛擬機器棧相同,唯一的區別是:虛擬機器棧是執行Java方法的,而本地方法棧是用來執行native方法的,在很多虛擬機器中(如Sun的JDK預設的HotSpot虛擬機器),會將本地方法棧與虛擬機器棧放在一起使用。

本地方法棧也是線程私人的。
  

2.4 堆區(Heap)

堆區是理解Java GC機制最重要的地區,沒有之一。在JVM所管理的記憶體中,堆區是最大的一塊,堆區也是Java GC機制所管理的主要記憶體地區,堆區由所有線程共用,在虛擬機器啟動時建立。堆區的存在是為了儲存物件執行個體,原則上講,所有的對象都在堆區上分配記憶體(不過現代技術裡,也不是這麼絕對的,也有棧上直接分配的)。

一般的,根據Java虛擬機器規範規定,堆記憶體需要在邏輯上是連續的(在物理上不需要),在實現時,可以是固定大小的,也可以是可擴充的,目前主流的虛擬機器都是可擴充的。如果在執行記憶體回收之後,仍沒有足夠的記憶體配置,也不能再擴充,將會拋出OutOfMemoryError:Java heap space異常。
  
關於堆區的內容還有很多,將在下節“Java記憶體配置機制”中詳細介紹。
  

2.5 方法區(Method Area)

在Java虛擬機器規範中,將方法區作為堆的一個邏輯部分來對待,但事實上,方法區並不是堆(Non-Heap);另外,不少人的部落格中,將Java GC的分代收集機制分為3個代:青年代,老年代,永久代,這些作者將方法區定義為“永久代”,這是因為,對於之前的HotSpot Java虛擬機器的實現方式中,將分代收集的思想擴充到了方法區,並將方法區設計成了永久代。不過,除HotSpot之外的多數虛擬機器,並不將方法區當做永久代,HotSpot本身,也計劃取消永久代。本文中,由於筆者主要使用Oracle JDK6.0,因此仍將使用永久代一詞。

方法區是各個線程共用的地區,用於儲存已經被虛擬機器載入的類資訊(即載入類時需要載入的資訊,包括版本、field、方法、介面等資訊)、final常量、靜態變數、編譯器即時編譯的代碼等。
  
方法區在物理上也不需要是連續的,可以選擇固定大小或可擴充大小,並且方法區比堆還多了一個限制:可以選擇是否執行垃圾收集。一般的,方法區上 執行的垃圾收集是很少的,這也是方法區被稱為永久代的原因之一(HotSpot),但這也不代表著在方法區上完全沒有垃圾收集,其上的垃圾收集主要是針對常量池的記憶體回收和對已載入類的卸載。
  
在方法區上進行垃圾收集,條件苛刻而且相當困難,效果也不令人滿意,所以一般不做太多考慮,可以留作以後進一步深入研究時使用。在方法區上定義了OutOfMemoryError:PermGen space異常,在記憶體不足時拋出。

運行時常量池(Runtime Constant Pool)是方法區的一部分,用於儲存編譯期就產生的字面常量、符號引用、翻譯出來的直接引用(符號引用就是編碼是用字串表示某個變數、介面的位置,直接引用就是根據符號引用翻譯出來的地址,將在類連結階段完成翻譯);運行時常量池除了儲存編譯期常量外,也可以儲存在已耗用時間產生的常量(比如String類的intern()方法,作用是String維護了一個常量池,如果調用的字元“abc”已經在常量池中,則返回池中的字串地址,否則,建立一個常量加入池中,並返回地址)。
  

2.6 直接記憶體(Direct Memory)

直接記憶體並不是JVM管理的記憶體,可以這樣理解,直接記憶體,就是 JVM以外的機器記憶體。比如,你有4G的記憶體,JVM佔用了1G,則其餘的3G就是直接記憶體,JDK中有一種基於通道(Channel)和緩衝區(Buffer)的記憶體配置方式,將由C語言實現的native函數庫分配在直接記憶體中,用儲存在JVM堆中的DirectByteBuffer來引用。由於直接記憶體收到本機器記憶體的限制,所以也可能出現OutOfMemoryError的異常。

本欄目將持續更新Java知識……

Java筆記-Java 記憶體地區和GC機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.