摘要:的的內(nèi)存可分為個(gè)區(qū)堆棧和方法區(qū)堆區(qū)存儲(chǔ)的是出來(lái)的對(duì)象和數(shù)組,每個(gè)對(duì)象都包含一個(gè)與之對(duì)應(yīng)的的信息。每個(gè)棧中的數(shù)據(jù)原始類型和對(duì)象引用都是私有的,其他棧不能訪問(wèn)。
JAVA的JVM的內(nèi)存可分為3個(gè)區(qū):堆(heap)、棧(stack)和方法區(qū)(method)
堆區(qū):1.存儲(chǔ)的是new出來(lái)的對(duì)象和數(shù)組,每個(gè)對(duì)象都包含一個(gè)與之對(duì)應(yīng)的class的信息。(class的目的是得到操作指令)
2.jvm只有一個(gè)堆區(qū)(heap)被所有線程共享,堆中不存放基本類型和對(duì)象引用,只存放對(duì)象本身
棧區(qū):1.每個(gè)線程包含一個(gè)棧區(qū),棧中保存的是所有的變量,包括基本類型和引用類型,棧中的每個(gè)變量都包含類型、名稱、值這些內(nèi)容,只不過(guò)基本類型變量的值為一個(gè)具體的值,而引用類型的變量的值為對(duì)象在堆中的地址。
2.每個(gè)棧中的數(shù)據(jù)(原始類型和對(duì)象引用)都是私有的,其他棧不能訪問(wèn)。
3.棧分為3個(gè)部分:基本類型變量區(qū)、執(zhí)行環(huán)境上下文、操作指令區(qū)(存放操作指令)。
方法區(qū):1.又叫靜態(tài)區(qū),跟堆一樣,被所有的線程共享。方法區(qū)包含所有的class和static變量。
2.方法區(qū)中包含的都是在整個(gè)程序中永遠(yuǎn)唯一的元素,如class,static變量。
3.字符串常量池就是存放在方法區(qū)。
堆和棧的不同:<1>存數(shù)數(shù)據(jù)不同
<2>回收方式不同
棧中當(dāng)超過(guò)變量的作用域后,java會(huì)自動(dòng)釋放掉為該變量分配的內(nèi)存空間,該內(nèi)存空間可以立刻被另作他用。數(shù)組和對(duì)象在沒(méi)有引用變量指向它的時(shí)候,才變成垃圾,不能再被使用,但是仍然占著內(nèi)存,在隨后的一個(gè)不確定的時(shí)間被垃圾回收器釋放掉。
<3>速度不同
堆中分配的內(nèi)存,由Java虛擬機(jī)的自動(dòng)垃圾回收器來(lái)管理。 堆和棧的優(yōu)缺點(diǎn):<1>堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,因?yàn)樗窃谶\(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存的,Java的垃圾收集器會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢.
<2>棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于寄存器,棧數(shù)據(jù)可以共享。但缺點(diǎn)是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性
編譯器先處理int a = 3;首先它會(huì)在棧中創(chuàng)建一個(gè)變量為a的引用,然后查找棧中是否有3這個(gè)值,如果沒(méi)找到,就將3存放進(jìn)來(lái),然后將a指向3。接著處理int b = 3;在創(chuàng)建完b的引用變量后,因?yàn)樵跅V幸呀?jīng)有3這個(gè)值,便將b直接指向3。這樣,就出現(xiàn)了a與b同時(shí)均指向3的情況。
這時(shí),如果再令a=4;那么編譯器會(huì)重新搜索棧中是否有4值,如果沒(méi)有,則將4存放進(jìn)來(lái),并令a指向4;如果已經(jīng)有了,則直接將a指向這個(gè)地址。
因此a值的改變不會(huì)影響到b的值。
系統(tǒng)收到了我們發(fā)出的指令,啟動(dòng)了一個(gè)Java虛擬機(jī)進(jìn)程,這個(gè)進(jìn)程首先從classpath中找到AppMain.class文件,讀取這個(gè)文件中的二進(jìn)制數(shù)據(jù),然后把Appmain類的類信息存放到運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)中。這一過(guò)程稱為AppMain類的加載過(guò)程。
接著,Java虛擬機(jī)定位到方法區(qū)中AppMain類的Main()方法的字節(jié)碼,開(kāi)始執(zhí)行它的指令。這個(gè)main()方法的第一條語(yǔ)句就是:Sample test1=new Sample("測(cè)試1");就是讓java虛擬機(jī)創(chuàng)建一個(gè)Sample實(shí)例,并且呢,使引用變量test1引用這個(gè)實(shí)例。就讓我們來(lái)跟蹤一下Java虛擬機(jī),看看它究竟是怎么來(lái)執(zhí)行這個(gè)任務(wù)的:
1、 Java虛擬機(jī)直奔方法區(qū),先找到Sample類的類型信息。結(jié)果這會(huì)兒的方法區(qū)里還沒(méi)有Sample類。于是立馬加載了Sample類,把Sample類的類型信息存放在方法區(qū)里。
2、 為一個(gè)新的Sample實(shí)例分配內(nèi)存, 這個(gè)Sample實(shí)例持有著指向方法區(qū)的Sample類的類型信息的引用。而這個(gè)引用地址,就存放了在Sample實(shí)例的數(shù)據(jù)區(qū)里。
3、 在JAVA虛擬機(jī)進(jìn)程中,每個(gè)線程都會(huì)擁有一個(gè)方法調(diào)用棧,用來(lái)跟蹤線程運(yùn)行中一系列的方法調(diào)用過(guò)程,棧中的每一個(gè)元素就被稱為棧幀,每當(dāng)線程調(diào)用一個(gè)方法的時(shí)候就會(huì)向方法棧壓入一個(gè)新幀。這里的幀用來(lái)存儲(chǔ)方法的參數(shù)、局部變量和運(yùn)算過(guò)程中的臨時(shí)數(shù)據(jù)。OK,原理講完了,就讓我們來(lái)繼續(xù)我們的跟蹤行動(dòng)!位于“=”前的Test1是一個(gè)在main()方法中定義的變量,可見(jiàn),它是一個(gè)局部變量,因此,它被會(huì)添加到了執(zhí)行main()方法的主線程的JAVA方法調(diào)用棧中。而“=”將把這個(gè)test1變量指向堆區(qū)中的Sample實(shí)例,也就是說(shuō),它持有指向Sample實(shí)例的引用。
接下來(lái),JAVA虛擬機(jī)將繼續(xù)執(zhí)行后續(xù)指令,在堆區(qū)里繼續(xù)創(chuàng)建另一個(gè)Sample實(shí)例,然后依次執(zhí)行它們的printName()方法。當(dāng)JAVA虛擬機(jī)執(zhí)行test1.printName()方法時(shí),JAVA虛擬機(jī)根據(jù)局部變量test1持有的引用,定位到堆區(qū)中的Sample實(shí)例,再根據(jù)Sample實(shí)例持有的引用,定位到方法去中Sample類的類型信息,從而獲得printName()方法的字節(jié)碼,接著執(zhí)行printName()方法包含的指令。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/76958.html
摘要:是描述方法執(zhí)行的內(nèi)存模型每個(gè)方法執(zhí)行的時(shí)候會(huì)同時(shí)創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量表操作數(shù)棧動(dòng)態(tài)連接返回地址方法出口等信息。虛擬機(jī)是使用局部變量表完成參數(shù)值到參數(shù)變量表的傳遞過(guò)程。堆內(nèi)存管理最大的一塊。 showImg(https://segmentfault.com/img/bVLqsv?w=475&h=398); 1. 虛擬機(jī)棧 VM Stack 線程私有,生命周期與線程相同。VM S...
摘要:虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域。棧幀棧幀是用于支持虛擬機(jī)進(jìn)行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu),它是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)中的虛擬機(jī)棧的棧元素。棧幀的概念結(jié)構(gòu)如下運(yùn)行時(shí)數(shù)據(jù)區(qū)腦圖高 這里我們先說(shuō)句題外話,相信大家在面試中經(jīng)常被問(wèn)到介紹Java內(nèi)存模型,我在面試別人時(shí)也會(huì)經(jīng)常問(wèn)這個(gè)問(wèn)題。但是,往往都會(huì)令我比較尷尬,我還話音未落,面試者就會(huì)背誦一段(Java虛擬...
摘要:在之后,原來(lái)永久代的數(shù)據(jù)被分到了堆和元空間中。元空間存儲(chǔ)類的元信息,靜態(tài)變量和常量池等放入堆中。這樣能在一些場(chǎng)景中顯著提高性能,因?yàn)楸苊饬嗽诙褍?nèi)存和堆外內(nèi)存來(lái)回拷貝數(shù)據(jù)。 以下內(nèi)容部分轉(zhuǎn)載于: CS-Notes showImg(http://ww1.sinaimg.cn/large/005NT19Ply1g385uooqv9j30kd0slmyw.jpg); 程序計(jì)數(shù)器(Program...
摘要:程序計(jì)數(shù)器程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。它的主要缺點(diǎn)有兩個(gè)一個(gè)是效率問(wèn)題,標(biāo)記和清除過(guò)程的效率都不 Jvm 相關(guān) 類加載機(jī)制 本段參考 http://www.importnew.com/2374... 類加載概念 類加載指的是將類的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個(gè)ja...
摘要:下面的截圖內(nèi)容來(lái)自從規(guī)范我們可以看到,規(guī)范要求的運(yùn)行時(shí)數(shù)據(jù)區(qū)域有程序計(jì)數(shù)器虛擬機(jī)棧堆方法區(qū)本地方法棧運(yùn)行時(shí)常量池這及部分。查了一下,還是沒(méi)有查到官方對(duì)于運(yùn)行時(shí)數(shù)據(jù)區(qū)域的說(shuō)明,但是許多博客都指出將字符串常量池移動(dòng)到了堆中。 不少java程序員一提JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)域,就會(huì)說(shuō)堆和棧,當(dāng)然也有java程序員給出方法區(qū)、虛擬機(jī)棧、本地方法棧、堆、程序計(jì)數(shù)器這個(gè)答案,但是還有人給出永久代、虛擬機(jī)...
閱讀 1025·2021-09-26 09:55
閱讀 3565·2021-09-24 10:30
閱讀 1369·2021-09-08 09:36
閱讀 2556·2021-09-07 09:58
閱讀 606·2019-08-30 15:56
閱讀 773·2019-08-29 18:32
閱讀 3615·2019-08-29 15:13
閱讀 1845·2019-08-29 13:49