版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Java數(shù)據(jù)類型及其在內(nèi)存存放的位置Java數(shù)據(jù)類型基本類型(primitive)引用類型(reference)數(shù)值型整數(shù)類型(byteshortintlong)浮點(diǎn)類型(floatdouble)字符型(char)布爾類型(boolean)類(class)接口(interface)數(shù)組(array)類型名稱占用存儲(chǔ)空間表數(shù)范圍默認(rèn)值byte字節(jié)8bit(即1個(gè)字節(jié))-128~127(-2^7~2^7-1)0short短整型16bit(即2個(gè)字節(jié))-32768~32717(-2^15~2^15-1)0int整型32bit(即4個(gè)字節(jié))-2^31~2^31-10long長整型64bit(即8個(gè)字節(jié))-2^63~2^63-10Lfloat單精度浮點(diǎn)型32bit(即4個(gè)字節(jié))-3.40E38~+3.40E380.0fdouble雙精度浮點(diǎn)型64bit(即8個(gè)字節(jié))-1.79E308~1.79E3080.0dchar字符型16bit(即2個(gè)字節(jié))0~65535‘\u0000’(空)boolean布爾類型8bit(即1個(gè)字節(jié))true,falsefalseJava基本數(shù)據(jù)類型(8種)基本數(shù)據(jù)類型packagetest01;publicclasstest1{publicstaticvoidmain(String[]args){inti=1;Intj=1;charch=“a“;System.out.println(i);System.out.println(ch);}棧1aij引用數(shù)據(jù)類型packagetest01;publicclasstest2{publicstaticvoidmain(String[]args){test2t2=newtest2();intreasult=t2.Rectangle(7,2020);System.out.println(reasult);}publicintRectangle(intwidth,intheight){ints=width*height;returns;}};棧堆newtest2()對象常量池110925t2對象的引用(引用變量的值為對象在堆中的首地址)packagetest01;importjava.util.ArrayList;publicclasstest2{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubint[]arr=newint[]{1,2};System.out.println(arr);ArrayList<Integer>arrayList=newArrayList<Integer>();arrayList.add(1);arrayList.add(2);System.out.println(arrayList);}};354725354720arrarrayList常量池1212packagetest01;publicclasstest3{publicstaticvoidmain(String[]args){Stringstr1="abc";Stringstr2="abc";Stringstr3=“bc”;Stringstr4=“def”;Stringstr5=“ab”+”c”;charch=“a”;Stringstr11=newString("abc");Stringstr22=newString("abc");Stringstr33=newString("ab");Stringstr44=newString("def");System.out.println(str1);System.out.println(str11);System.out.println(str1==str2);}//輸出trueSystem.out.println(str1==str5);//輸出trueSystem.out.println(str11==str22)//輸出falseSystem.out.println(str1==str11);}//輸出false}};棧堆a(bǔ)bc110925new
String(“abc”)110925str1str11587934常量池ach………str22354752str2new
String(“abc”)棧:保存局部變量的值,包括:1.用來保存基本數(shù)據(jù)類型的值;2.保存類的實(shí)例,即堆區(qū)對象的引用(指針)。也可以用來保存加載方法時(shí)的幀。
堆:用來存放動(dòng)態(tài)產(chǎn)生的數(shù)據(jù),比如new出來的對象。注意創(chuàng)建出來的對象只包含屬于各自的成員變量,并不包括成員方法。因?yàn)橥粋€(gè)類的對象擁有各自的成員變量,存儲(chǔ)在各自的堆中,但是他們共享該類的方法,并不是每創(chuàng)建一個(gè)對象就把成員方法復(fù)制一次。常量池:JVM為每個(gè)已加載的類型維護(hù)一個(gè)常量池,常量池就是這個(gè)類型用到的常量的一個(gè)有序集合。包括直接常量(基本類型,String)和對其他類型、方法、字段的符號引用。池中的數(shù)據(jù)和數(shù)組一樣通過索引訪問。由于常量池包含了一個(gè)類型所有的對其他類型、方法、字段的符號引用,所以常量池在Java的動(dòng)態(tài)鏈接中起了核心作用。常量池存在于堆中。三個(gè)關(guān)鍵存儲(chǔ)運(yùn)行時(shí)數(shù)據(jù)的地方(棧,堆,常量池)一:在方法中聲明的變量,即該變量是局部變量,每當(dāng)程序調(diào)用方法時(shí),系統(tǒng)都會(huì)為該方法建立一個(gè)方法棧,其所在方法中聲明的變量就放在方法棧中,當(dāng)方法結(jié)束系統(tǒng)會(huì)釋放方法棧,其對應(yīng)在該方法中聲明的變量隨著棧的銷毀而結(jié)束,這就局部變量只能在方法中有效的原因
在方法中聲明的變量可以是基本類型的變量,也可以是引用類型的變量。
(1)當(dāng)聲明是基本類型的變量的時(shí),其變量名及值(變量名及值是兩個(gè)概念)是放在JAVA虛擬機(jī)棧中
(2)當(dāng)聲明的是引用(變量時(shí),所聲明的變量(該變量實(shí)際上是在方法中存儲(chǔ)的是內(nèi)存地址值)是放在 JAVA虛擬機(jī)的棧中,該變量所指向的對象是放在堆類存中的。二:在類中聲明的變量是成員變量,也叫全局變量,放在堆中的(因?yàn)槿肿兞坎粫?huì)隨著某個(gè)方法執(zhí)行結(jié)束而銷毀)。
同樣在類中聲明的變量即可是基本類型的變量也可是引用類型的變量
(1)當(dāng)聲明的是基本類型的變量其變量名及其值放在堆內(nèi)存中的
(2)引用類型時(shí),其聲明的變量仍然會(huì)存儲(chǔ)一個(gè)內(nèi)存地址值,該內(nèi)存地址值指向所引用的對象。引用變
量名和對應(yīng)的對象仍然存儲(chǔ)在相應(yīng)的堆中。java中的基本數(shù)據(jù)類型一定存儲(chǔ)在棧中的嗎?錯(cuò)基本數(shù)據(jù)類型是放在棧中還是放在堆中,這取決于基本類型在何處聲明Java代碼
classBirthDate{
privateintday;
privateintmonth;
privateintyear;
publicBirthDate(intd,intm,inty){
day=d;
month=m;
year=y;
}省略get,set方法………
}publicclassTest{
publicstaticvoidmain(Stringargs[]){
intdate=9;
Testtest=newTest();
test.change(date);
BirthDated1=newBirthDate(7,7,1970);
}
publicvoidchange(inti){
i=1234;
}對于以上這段代碼,date為局部變量,i,d,m,y都是形參為局部變量,day,month,year為成員變量。下面分析一下代碼執(zhí)行時(shí)候的變化:
1.main方法開始執(zhí)行:intdate=9;
date局部變量,基礎(chǔ)類型,引用和值都存在棧中。
2.Testtest=newTest();
test為對象引用,存在棧中,對象(newTest())存堆中。
3.test.change(date);
i為局部變量,引用和值存在棧中。當(dāng)方法change執(zhí)行完
成后,i就會(huì)從棧中消失。
4.BirthDated1=newBirthDate(7,7,1970);
d1為對象引用,存在棧中,對象(newBirthDate())存在堆中,其中d,m,y為局部變量存儲(chǔ)在棧中,且它們的類型為基礎(chǔ)類型,因此它們的數(shù)據(jù)也存儲(chǔ)在棧中。day,month,year為成員變量,它們存儲(chǔ)在堆中(newBirthDate()里面)。當(dāng)BirthDate構(gòu)造方法執(zhí)行完之后,d,m,y將從棧中消失。
5.main方法執(zhí)行完之后,date變量,test,d1引用將從棧中消失,newTest(),newBirthDate()將等待垃圾回收。Java內(nèi)存分析JavaCompiler(Java編譯器)Java源程序(*.Java)Java字節(jié)碼文件(*.class)Classloader(類加載器)ExecutionEngine(執(zhí)行引擎)Nativeinterface(本地方法接口)NativeLibraries(本地方法庫)RuntimeDataArea(運(yùn)行時(shí)數(shù)據(jù)區(qū))JavaVirtualMachine方法區(qū)MethodAreaJavaRuntimeAreaJava運(yùn)行時(shí)數(shù)據(jù)區(qū)Java虛擬機(jī)棧JavaStackJava本地方法棧NativeMethodStackJava堆Heap程序計(jì)數(shù)器ProgramCounterRegister每個(gè)線程對象獨(dú)享所有線程對象共享?xiàng)#↗avaStack):又叫堆棧。JVM為每個(gè)新創(chuàng)建的線程都分配一個(gè)棧。也就是說,對于一個(gè)Java程序來說,它的運(yùn)行就是通過對棧的操作來完成的。棧以幀為單位保存線程的狀態(tài)。JVM對棧只進(jìn)行兩種操作:以幀為單位的壓棧和出棧操作。我們知道,某個(gè)線程正在執(zhí)行的方法稱為此線程的當(dāng)前方法。我們可能不知道,當(dāng)前方法使用的幀稱為當(dāng)前幀。當(dāng)線程激活一個(gè)Java方法,JVM就會(huì)在線程的Java堆棧里新壓入一個(gè)幀,這個(gè)幀自然成為了當(dāng)前幀。在此方法執(zhí)行期間,這個(gè)幀將用來保存參數(shù)、局部變量、中間計(jì)算過程和其他數(shù)據(jù)。從Java的這種分配機(jī)制來看,堆棧又可以這樣理解:棧(Stack)是操作系統(tǒng)在建立某個(gè)進(jìn)程時(shí)或者線程(在支持多線程的操作系統(tǒng)中是線程)為這個(gè)線程建立的存儲(chǔ)區(qū)域,該區(qū)域具有先進(jìn)后出的特性。其相關(guān)設(shè)置參數(shù):-Xss–設(shè)置方法棧的最大值本地方法棧(NativeMethodStack):存儲(chǔ)本地方方法的調(diào)用狀態(tài)。程序計(jì)數(shù)器(ProgramCountRegister):又叫程序寄存器。JVM支持多個(gè)線程同時(shí)運(yùn)行,當(dāng)每一個(gè)新線程被創(chuàng)建時(shí),它都將得到它自己的PC寄存器(程序計(jì)數(shù)器)。如果線程正在執(zhí)行的是一個(gè)Java方法(非native),那么PC寄存器的值將總是指向下一條將被執(zhí)行的指令,如果方法是native的,程序計(jì)數(shù)器寄存器的值不會(huì)被定義。JVM的程序計(jì)數(shù)器寄存器的寬度足夠保證可以持有一個(gè)返回地址或者native的指針。堆(Heap):Java堆(JavaHeap)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域。在此區(qū)域的唯一目的就是存放對象實(shí)例,幾乎所有的對象實(shí)例都是在這里分配內(nèi)存,但是這個(gè)對象的引用卻是在棧(Stack)中分配。比如,執(zhí)行Strings=newString(“s”)時(shí),需要從兩個(gè)地方分配內(nèi)存:在堆中為String對象分配內(nèi)存,在棧中為引用(這個(gè)堆對象的內(nèi)存地址,即指針)。線程這里所說的線程指程序執(zhí)行過程中的一個(gè)線程實(shí)體。JVM允許一個(gè)應(yīng)用并發(fā)執(zhí)行多個(gè)線程。HotspotJVM中的Java線程與原生操作系統(tǒng)線程有直接的映射關(guān)系。當(dāng)線程本地存儲(chǔ)、緩沖區(qū)分配、同步對象、棧、程序計(jì)數(shù)器等準(zhǔn)備好以后,就會(huì)創(chuàng)建一個(gè)操作系統(tǒng)原生線程。Java線程結(jié)束,原生線程隨之被回收。操作系統(tǒng)負(fù)責(zé)調(diào)度所有線程,并把它們分配到任何可用的CPU上。當(dāng)原生線程初始化完畢,就會(huì)調(diào)用Java線程的run()方法。run()返回時(shí),被處理未捕獲異常,原生線程將確認(rèn)由于它的結(jié)束是否要終止JVM進(jìn)程(比如這個(gè)線程是最后一個(gè)非守護(hù)線程)。當(dāng)線程結(jié)束時(shí),會(huì)釋放原生線程和Java線程的所有資源。JVM系統(tǒng)線程如果使用jconsole或者其它調(diào)試器,你會(huì)看到很多線程在后臺運(yùn)行。這些后臺線程與觸發(fā)publicstaticvoidmain(String[])函數(shù)的主線程以及主線程創(chuàng)建的其他線程一起運(yùn)行。HotspotJVM后臺運(yùn)行的系統(tǒng)線程主要有右面幾個(gè):虛擬機(jī)線程(VMthread這個(gè)線程等待JVM到達(dá)安全點(diǎn)操作出現(xiàn)。這些操作必須要在獨(dú)立的線程里執(zhí)行,因?yàn)楫?dāng)堆修改無法進(jìn)行時(shí),線程都需要JVM位于安全點(diǎn)。這些操作的類型有:stop-the-world垃圾回收、線程棧dump、線程暫停、線程偏向鎖(biasedlocking)解除。周期性任務(wù)線程這線程負(fù)責(zé)定時(shí)器事件(也就是中斷),用來調(diào)度周期性操作的執(zhí)行。GC線程這些線程支持JVM中不同的垃圾回收活動(dòng)。編譯器線程這些線程在運(yùn)行時(shí)將字節(jié)碼動(dòng)態(tài)編譯成本地平臺相關(guān)的機(jī)器碼。信號分發(fā)線程這個(gè)線程接收發(fā)送到JVM的信號并調(diào)用適當(dāng)?shù)腏VM方法處理。線程一線程三線程二PC寄存器棧幀棧幀棧幀棧幀棧幀棧幀棧幀線程三Java棧本地方法棧線程一線程三線程二棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)局部變量表操作數(shù)棧指向運(yùn)行時(shí)常量的引用方法返回地址動(dòng)態(tài)鏈接棧頂(當(dāng)前方法)(StackFrame)Java虛擬機(jī)棧(JavaVirtualMachineStacks)1.棧內(nèi)存是線程共有的,其生命周期與線程相同。2.虛擬機(jī)描述的是Java方法執(zhí)行的內(nèi)存模型:執(zhí)行一個(gè)方法會(huì)產(chǎn)生一個(gè)棧幀,隨后將其保存到棧(后進(jìn)先出)的頂部,方法執(zhí)行完畢后會(huì)自動(dòng)將此棧幀進(jìn)行出棧。頂部的棧幀表示的就是當(dāng)前的方法。如果請求的棧的深度過大,虛擬機(jī)可能會(huì)拋出StackOverflowError異常如果虛擬機(jī)的實(shí)現(xiàn)中允許,虛擬機(jī)棧動(dòng)態(tài)擴(kuò)展,當(dāng)內(nèi)存不足以擴(kuò)展棧的時(shí)候,會(huì)拋出OutOfMemory異常。局部變量表(LocalVariables):方法的局部變量或形參,其以變量槽(solt)為最小單位,只允許保存32位長度的變量,如果超過32位則會(huì)開辟兩個(gè)連續(xù)的solt(64位,long和double)。操作數(shù)棧(OperandStack):表達(dá)式計(jì)算在棧中完成。指向當(dāng)前方法所屬的類的運(yùn)行時(shí)常量池的引用(ReferencetoRuntimeConstantPool):引用其他類的常量或者使用String池中的字符串。方法返回地址(ReturnAddress):方法執(zhí)行完成后需要返回調(diào)用此方法的位置,所以需要在棧中保存方法的返回地址。動(dòng)態(tài)鏈接(dynamiclinking):每個(gè)棧幀都有一個(gè)運(yùn)行時(shí)常量池的引用。這個(gè)引用指向棧幀當(dāng)前運(yùn)行方法所在類的常量池。通過這個(gè)引用支持動(dòng)態(tài)鏈接(dynamiclinking)。C/C++代碼一般被編譯成對象文件,然后多個(gè)對象文件被鏈接到一起產(chǎn)生可執(zhí)行文件或者dll。在鏈接階段,每個(gè)對象文件的符號引用被替換成了最終執(zhí)行文件的相對偏移內(nèi)存地址。在Java中,鏈接階段是運(yùn)行時(shí)動(dòng)態(tài)完成的。當(dāng)Java類文件編譯時(shí),所有變量和方法的引用都被當(dāng)做符號引用存儲(chǔ)在這個(gè)類的常量池中。符號引用是一個(gè)邏輯引用,實(shí)際上并不指向物理內(nèi)存地址。JVM可以選擇符號引用解析的時(shí)機(jī),一種是當(dāng)類文件加載并校驗(yàn)通過后,這種解析方式被稱為饑餓方式。另外一種是符號引用在第一次使用的時(shí)候被解析,這種解析方式稱為惰性方式。無論如何,JVM必須要在第一次使用符號引用時(shí)完成解析并拋出可能發(fā)生的解析錯(cuò)誤。綁定是將對象域、方法、類的符號引用替換為直接引用的過程。綁定只會(huì)發(fā)生一次。一旦綁定,符號引用會(huì)被完全替換。如果一個(gè)類的符號引用還沒有被解析,那么就會(huì)載入這個(gè)類。每個(gè)直接引用都被存儲(chǔ)為相對于存儲(chǔ)結(jié)構(gòu)(與運(yùn)行時(shí)變量或方法的位置相關(guān)聯(lián)的)偏移量。運(yùn)行時(shí)常量池堆數(shù)據(jù)類型數(shù)字型字符串型類引用型域引用型方法引用數(shù)據(jù)類型對象(實(shí)例)數(shù)組publicclassdemo{publicstaticvoidmain(String[]args){Stringa="abc";int[]a1={1,2,3};System.out.println(a);System.out.println(a1[0]);}}Class文件中的常量池:在Class文件結(jié)構(gòu)中,最頭的4個(gè)字節(jié)用于存儲(chǔ)魔數(shù)MagicNumber,用于確定一個(gè)文件是否能被JVM接受,再接著4個(gè)字節(jié)用于存儲(chǔ)版本號,前2個(gè)字節(jié)存儲(chǔ)次版本號,后2個(gè)存儲(chǔ)主版本號,再接著是用于存放常量的常量池,由于常量的數(shù)量是不固定的,所以常量池的入口放置一個(gè)U2類型的數(shù)據(jù)(constant_pool_count)存儲(chǔ)常量池容量計(jì)數(shù)值。
常量池主要用于存放兩大類常量:字面量(Literal)和符號引用量(SymbolicReferences),字面量相當(dāng)于Java語言層面常量的概念,如文本字符串,聲明為final的常量值等,符號引用則屬于編譯原理方面的概念,包括了如下三種類型的常量:類和接口的全限定名字段名稱和描述符方法名稱和描述符詳細(xì)請看連接:/p/c7f47de2ee80Integer4字節(jié)常量Long8字節(jié)常量Float4字節(jié)常量Double8字節(jié)常量String字符串常量指向常量池的另外一個(gè)包含真正字節(jié)Utf8編碼的實(shí)體Utf8Utf8編碼的字符序列字節(jié)流Class一個(gè)Class常量,指向常量池的另一個(gè)Utf8實(shí)體,這個(gè)實(shí)體包含了符合JVM內(nèi)部格式的類的全名(動(dòng)態(tài)鏈接過程需要用到)NameAndType冒號(:)分隔的一組值,這些值都指向常量池中的其它實(shí)體。第一個(gè)值(“:”之前的)指向一個(gè)Utf8字符串實(shí)體,它是一個(gè)方法名或者字段名。第二個(gè)值指向表示類型的Utf8實(shí)體。對于字段類型,這個(gè)值是類的全名,對于方法類型,這個(gè)值是每個(gè)參數(shù)類型類的類全名的列表。Fieldref,Methodref,InterfaceMethodref點(diǎn)號(.)分隔的一組值,每個(gè)值都指向常量池中的其它的實(shí)體。第一個(gè)值(“.”號之前的)指向類實(shí)體,第二個(gè)值指向NameAndType實(shí)體。這個(gè)常量池包含了下面的類型JavaMemoryModelHeapPermGen(MethodArea)ThreadYoungGenerationOld/TenuredGenerationEdenSpace(Survivor0)FromSpace(Survivor1)ToSpaceVMMetaspaceJava8中替換成了VMMetaspaceHeap-sharedamongallthreads
(globle)-StoresallcreatedobjectsandarraysMethodArea-sharedamongallthreads(globle)-Storesclassstructureslikefieldandmethoddata,codeformetholdsandconstructors,etcThread-privatestack(local)-Holdsreferencestoobjectsintheheap-StorelocalvariablesofprimitivetypesHeapSpaceMethodAreaNativeAreaYoungGenerationOldGenerationPermanentGenerationCodeCacheVirtualFr
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 紙張修復(fù)課程設(shè)計(jì)思路
- 招聘焊工企業(yè)合同范例
- 水電安裝讓利合同范例
- 污水管合同范例
- 樣給客戶寫銷售合同范例
- 養(yǎng)生會(huì)所合作合同范本3篇
- 井下作業(yè)合同范本3篇
- 合作經(jīng)營協(xié)議書的格式3篇
- 字草原轉(zhuǎn)讓承包合同范本3篇
- 二手車買賣合同法規(guī)3篇
- 北京市房山區(qū)2023-2024學(xué)年三年級上學(xué)期期末數(shù)學(xué)試卷
- 2024年中考英語二輪復(fù)習(xí)學(xué)案連詞
- 《中國建筑股份有限公司施工企業(yè)質(zhì)量管理辦法》
- 肛腸科患者的疼痛管理策略與實(shí)踐經(jīng)驗(yàn)
- 風(fēng)電項(xiàng)目投資計(jì)劃書
- 山東省醫(yī)療收費(fèi)目錄
- 在線開放課程申報(bào)書(成功申報(bào))
- JGT266-2011 泡沫混凝土標(biāo)準(zhǔn)規(guī)范
- 特種設(shè)備鍋爐日管控、周排查、月調(diào)度主要項(xiàng)目及內(nèi)容表
- 配電室運(yùn)行維護(hù)投標(biāo)方案(技術(shù)標(biāo))
- 快手申訴文本
評論
0/150
提交評論