1. 程式人生 > >java堆、棧、方法區、常量池

java堆、棧、方法區、常量池

1:棧

   在函式中定義的一些基本型別的變數資料和物件的引用變數都在函式的棧記憶體中分配。 

   當在一段程式碼塊定義一個變數時,Java就在棧中為這個變數分配記憶體空間,當該變數退出該作用域後,Java會自動釋放掉為該變數所分配的記憶體空間,該記憶體空間可以立即被另作他用。

   每個執行緒包含一個棧區,每個棧中的資料(原始型別和物件引用)都是私有的,其他棧不能訪問。棧分為3個部分:基本型別變數區、執行環境上下文、操作指令區(存放操作指令)。

2:堆

   堆記憶體用來存放由new建立的物件和陣列。 在堆中分配的記憶體,由Java虛擬機器的自動垃圾回收器來管理。在堆中產生了一個數組或物件後,在棧中定義一個特殊的變數,讓棧中這個變數的取值等於陣列或物件在堆記憶體中的首地址,棧中的這個變數就成了陣列或物件的引用變數。  引用變數就相當於是為陣列或物件起的一個名稱,以後就可以在程式中使用棧中的引用變數來訪問堆中的陣列或物件。引用變數就相當於是為陣列或者物件起的一個名稱。引用變數是普通的變數,定義時在棧中分配,引用變數在程式執行到其作用域之外後被釋放。而陣列和物件本身在堆中分配,即使程式執行到使用 new 產生陣列或者物件的語句所在的程式碼塊之外,陣列和物件本身佔據的記憶體不會被釋放,陣列和物件在沒有引用變數指向它的時候,才變為垃圾,不能在被使用,但仍然佔據記憶體空間不放,在隨後的一個不確定的時間被垃圾回收器收走(釋放掉)。這也是java比較佔記憶體的原因。實際上,棧中的變數指向堆記憶體中的變數,這就是java中的指標! 

   Java的堆是一個執行時資料區,類的物件從中分配空間。這些物件通過new、newarray、anewarray和multianewarray等指令建立,它們不需要程式程式碼來顯式的釋放。堆是由垃圾回收來負責的,堆的優勢是可以動態地分配記憶體大小,生存期也不必事先告訴編譯器,因為它是在執行時動態分配記憶體的,Java的垃圾收集器會自動收走這些不再使用的資料。但缺點是,由於要在執行時動態分配記憶體,存取速度較慢。

   jvm只有一個堆區(heap)被所有執行緒共享。

3、方法區(method area)

   方法區跟堆一樣,被所有的執行緒共享。用於儲存虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。

4、常量池(constant pool)

   常量池指的是在編譯期被確定,並被儲存在已編譯的.class檔案中的一些資料。除了包含程式碼中所定義的各種基本型別(如int、long等等)和物件型(如String及陣列)的常量值(final)還包含一些以文字形式出現的符號引用,比如:類和介面的全限定名; 欄位的名稱和描述符; 方法和名稱和描述符。虛擬機器必須為每個被裝載的型別維護一個常量池。常量池就是該型別所用到常量的一個有序集和,包括直接常量(string,integer和floating point常量)和對其他型別,欄位和方法的符號引用。對於String常量,它的值是在常量池中的。而JVM中的常量池在記憶體當中是以表的形式存在的,對於String型別,有一張固定長度的CONSTANT_String_info表用來儲存文字字串值,注意:該表只儲存文字字串值,不儲存符號引用。說到這裡,對常量池中的字串值的儲存位置應該有一個比較明瞭的理解了。

在程式執行的時候,常量池會儲存在方法區(Method Area),而不是堆中。

   棧的優勢是,存取速度比堆要快,僅次於暫存器,棧資料可以共享(指的是執行緒共享,而給程序共享)。但缺點是,存在棧中的資料大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本型別的變數資料(int, short, long, byte, float, double, boolean, char)和物件控制代碼(引用)。

相關推薦

關於方法

內存 線程 包含 信息 執行 引用 基礎 -s 只有一個 JAVA的JVM的內存可分為3個區:堆(heap)、棧(stack)和方法區(method)   堆區:   1.存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令)

目錄 1.1. JVM記憶體模型總體架構圖 1 1.2. JAVA 2 1.3. 方法 元空間(Metaspace) 2 1.4. 虛擬機器 3 1.5. 本地方法 4 2. 垃圾回收演算法 4 2

目錄 1.1. JVM記憶體模型總體架構圖 1 1.2. JAVA堆 2 1.3. 方法區 元空間(Metaspace) 2 1.4. 虛擬機器棧 3 1.5. 本地方法區 4 2. 垃圾回收演算法 4 2.1. 標記-清除演算法(Mark-Sweep) 4

Java JVM 中 方法 詳解

一 jvm執行時資料區有哪些 我們先來看一張圖 JVM執行時資料區分類 1. JVM棧 (Java Virtual Machine Stacks) 2. 堆記憶體 (Heap Memory) 3. 方法區 (Method Area) 4.

Java記憶體區域——方法

執行時資料區域 jdk1.7中, Java虛擬機器在執行Java程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。 程式計數器 1. 程式計數器(Program Counter Register)是一塊較小的記憶體空間,它

jvm虛擬機器初識(方法

堆(FIFO先進先出): 存放的是物件也就是new 的資訊也包括class物件,每new一個資訊,就會為物件分配堆記憶體區域,堆分配了物件的空間,當垃圾回收器檢測到某物件未被引用,則自動銷燬該物件,如果忘記銷燬物件,那麼它的記憶體空間還在。就會導致記憶體洩漏。- 和程式開發密切相關

JVM記憶體結構------方法,以及的區別

一 、 定義 堆:FIFO佇列優先,先進先出。JVM只有一個堆區被所有執行緒所共享!堆存放在耳機快取中,呼叫物件的速度相對慢一些,生命週期由JVM的垃圾回收機制定。 棧:FILO先進後出,暫存資料的地方。每個執行緒都包含一個棧區!棧存放在一級快取中,存取速度較快,“棧是限定

java中的字串到底是在方法常量裡還是new出來的物件裡

String實質是字元陣列,兩個特點:1、該類不可被繼承;2、不可變性(immutable)例如 String s1 = new String("myString");和 String s1 = "myString"; 第一種方式通過關鍵字new定義過程:在程式編譯期,編譯程

方法常量

        最近一直被方法區裡面存著什麼東西困擾著?        1.方法區裡存class檔案資訊和class檔案常量池是個什麼關係。         2.class檔案常量池和執行時常量池是什麼關係。         方法區存著類的資訊,常量和靜態變數,即類被編譯

Java方法

Java方法區、棧及堆 一 方法區(Method Area) 1. 什麼是方法區(Method Area)? 《深入理解JVM》書中對方法區(Method Area)描述如下: 方法區(Method Area)與Java堆一樣,是各個執行緒共享的記憶體區域。 2.方法區(Method Are

java 方法常量以及變數的記憶體分配

最近在看一些面試的相關問題,發現自己對java底層變數記憶體的分配理解不是很透徹,於是網上各種找資料,看了許多篇別人的部落格,於是自己也整理了一下,下面分享給各位:堆中Java虛擬機器的自動垃圾回收:引用變數是普通的變數,定義時在棧中分配,引用變數在程式執行到其作用域之外後被

java方法常量

1:棧    在函式中定義的一些基本型別的變數資料和物件的引用變數都在函式的棧記憶體中分配。     當在一段程式碼塊定義一個變數時,Java就在棧中為這個變數分配記憶體空間,當該變數退出該作用域後,Java會自動釋放掉為該變數所分配的記憶體空間,該記憶體空間可以立即

JVM執行時資料區域 —— 程式計數器Java虛擬機器本地方法Java方法執行時常量

java虛擬機器執行時資料區域的概括圖如下所示: 下面將對執行時資料區進行講解 程式計數器 1、說明:程式計數器可以看做是當前執行緒所執行的位元組碼的行號指示器。其實通俗點講就是記錄class檔案執行到哪一行 2、注意的點: (1)因為CPU執

1.1JVM記憶體結構——方法直接記憶體區別

一、定義 1、堆:FIFO佇列優先,先進先出。jvm只有一個堆區被所有執行緒所共享!堆存放在二級快取中,呼叫物件的速度相對慢一些,生命週期由虛擬機器的垃圾回收機制定。2、棧:FILO先進後出,暫存資料的地方。每個執行緒都包含一個棧區!棧存放在一級快取中,存取速度較快,“棧是限

方法直接記憶體區別

       新生區是類的誕生、成長、消亡的區域,一個類在這裡產生,應用,最後被垃圾回收器收集,結束生命。新生區又分為兩部分:伊甸區(Eden space)和倖存者區(Survivor pace),所有的類都是在伊甸區被new出來的。倖存區有兩個:0區(Survivor 0 space)和1區(Survivo

JVM的記憶體區域劃分-- 方法本地方法程式計數器

                          JVM的記憶體區域劃分   學過C語言的朋友都知道C編譯器在劃分記憶體區域的時候經常將管理的區域劃分為資料段和程式碼段,資料段包括堆、棧以及靜態資料區。那麼在Java語言當中,記憶體又是如何劃分的呢?   由於Jav

方法常量面試遇到怎麼答?

結構化語言裡函式(子程式)呼叫最方便的實現方式就是用棧,以至於現在絕大部分晶片都對棧提供晶片級的硬體支援,一條指令即可搞定棧的pop操作。棧的好處是:方便、快、有效避免記憶體碎片化。棧的問題是:不利於管理大記憶體(尤其在16位和32位時代)、資料的生命週期難於控制(棧內的有效

℃江的觀後感 -- Java 虛擬機器的方法直接記憶體和執行時常量

方法區 我們知道方法區,當然是和方法有關,Java虛擬機器的作用就兩個,儲存、運算。其實我們叫其方法區,說明和儲存東西有關,但是存什麼呢?這塊儲存的是虛擬機器載入的類資訊,常亮,靜態變數和有個就是即使編譯後的程式碼等資料。方法區一般在hotspot被稱為永久代

Java --- (heap)(stack)和方法(method)

java 的記憶體分為兩類,一類是棧記憶體,一類是堆記憶體。 棧記憶體是指程式進入一個方法時,會為這個方法單獨分配一塊私屬儲存空間,用於儲存這個方法內部的區域性變數,當這個方法 結束時,分配給這個方法的棧會釋放,這個棧中的變數也將隨之釋放。 堆是與棧作用不同的記憶體,一般用於存放不放在當前方法棧中的

JAVA基礎初探(五)繼承父子繼承的初始化順序子類方法重寫super關鍵字final關鍵字

該篇部落格目錄 1、JAVA繼承 2、父子繼承的初始化順序 3、子類方法的重寫 4、super關鍵字 5、final關鍵字 一、JAVA繼承 多個類中存在相同屬性和方法時,將這些內容抽取到一個類中,那麼多個類無需再

Java空間的劃分:新生代老年代

預設Eden:S0:S1=8:1:1,因此,新生代中可以使用的記憶體空間大小佔用新生代的9/10,那麼有人就會問,為什麼不直接分成兩個區,一個區佔9/10,另一個區佔1/10,這樣做的原因大概有以下幾種  1.S0與S1的區間明顯較小,有效新生代空間為Eden+S0/S1,因此有效空間就大,增加了記憶體使用率