Java內(nèi)存分配的原理與工作機(jī)制
一、Java虛擬機(jī)內(nèi)存原型Java虛擬機(jī)內(nèi)存分為寄存器、棧、堆、靜態(tài)域和常量池等幾個(gè)部分。其中,寄存器用于存放基本類型的數(shù)據(jù)和對象的引用,而對象本身存放在堆中。靜態(tài)域用于存放類中使用static定義的
一、Java虛擬機(jī)內(nèi)存原型
Java虛擬機(jī)內(nèi)存分為寄存器、棧、堆、靜態(tài)域和常量池等幾個(gè)部分。其中,寄存器用于存放基本類型的數(shù)據(jù)和對象的引用,而對象本身存放在堆中。靜態(tài)域用于存放類中使用static定義的靜態(tài)成員變量。常量池存放編譯期確定的常量和符號(hào)引用。而非RAM存儲(chǔ)則指的是硬盤等永久存儲(chǔ)空間。
二、常量池(constant pool)
常量池是在編譯期被確定,并保存在已編譯的.class文件中的一些數(shù)據(jù)。除了包含代碼中所定義的各種基本類型和對象類型的常量值外,還包括一些以文本形式出現(xiàn)的符號(hào)引用,如類和接口的全限定名、字段的名稱和描述符、方法的名稱和描述符等。虛擬機(jī)需要為每個(gè)被加載的類型維護(hù)一個(gè)常量池,它是該類型所使用的常量的有序集合。常量池在內(nèi)存中以表的形式存在,對于String類型的常量來說,它的值存儲(chǔ)在常量池中的Method Area,而不是堆中。
三、Java內(nèi)存分配中的棧
棧是Java虛擬機(jī)中內(nèi)存分配的基本單位,每當(dāng)一個(gè)線程執(zhí)行某個(gè)Java方法時(shí),Java虛擬機(jī)會(huì)為該線程分配一個(gè)Java棧。棧的幀用于存儲(chǔ)參數(shù)、局部變量、操作數(shù)、中間運(yùn)算結(jié)果等。棧上的數(shù)據(jù)是私有的,其他線程不能訪問該線程的棧數(shù)據(jù)。在函數(shù)中定義的基本類型的變量和對象的引用變量都在棧內(nèi)存中分配。當(dāng)在代碼塊中定義一個(gè)變量時(shí),Java會(huì)在棧中為該變量分配內(nèi)存空間,并在該變量退出作用域后自動(dòng)釋放所分配的內(nèi)存空間。
四、Java內(nèi)存分配中的堆
Java虛擬機(jī)中的堆用于存放使用new創(chuàng)建的對象和數(shù)組。堆的內(nèi)存由Java虛擬機(jī)的垃圾回收機(jī)制來管理。堆主要用于存放Java對象,而棧主要用于存放對象的引用。當(dāng)在堆中創(chuàng)建一個(gè)數(shù)組或?qū)ο蠛螅梢栽跅V卸x一個(gè)特殊的變量來引用該數(shù)組或?qū)ο笤诙褍?nèi)存中的首地址。堆中的對象在沒有引用變量指向它時(shí)才會(huì)變?yōu)槔?,被垃圾回收器回收?/p>
Java的堆是一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū),用于存儲(chǔ)類的對象。堆的大小可以動(dòng)態(tài)地分配,不需要事先告訴編譯器。堆的優(yōu)勢是可以動(dòng)態(tài)分配內(nèi)存大小,但存取速度較慢。與堆相比,棧的存取速度較快,但數(shù)據(jù)大小和生存期必須是確定的。棧主要存放基本類型的變量數(shù)據(jù)和對象句柄(引用)。棧中的數(shù)據(jù)可以共享,即多個(gè)變量可以指向同一個(gè)值。
總結(jié):
Java內(nèi)存分為棧、堆、常量池等幾個(gè)部分。棧用于存放基本類型的數(shù)據(jù)和對象的引用,而對象本身存放在堆中。常量池存放編譯期確定的常量和符號(hào)引用。棧的數(shù)據(jù)是私有的,其他線程不能訪問。堆用于存放使用new創(chuàng)建的對象和數(shù)組,由垃圾回收機(jī)制管理。堆的優(yōu)勢是可以動(dòng)態(tài)分配內(nèi)存大小,但存取速度較慢;棧的優(yōu)勢是存取速度快,但數(shù)據(jù)大小和生存期必須確定。