java數(shù)據(jù)類型及其內(nèi)存分配_第1頁
java數(shù)據(jù)類型及其內(nèi)存分配_第2頁
java數(shù)據(jù)類型及其內(nèi)存分配_第3頁
java數(shù)據(jù)類型及其內(nèi)存分配_第4頁
java數(shù)據(jù)類型及其內(nèi)存分配_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

Java數(shù)據(jù)類型及其在內(nèi)存存放的位置Java數(shù)據(jù)類型基本類型(primitive)引用類型(reference)數(shù)值型整數(shù)類型(byteshortintlong)浮點類型(floatdouble)字符型(char)布爾類型(boolean)類(class)接口(interface)數(shù)組(array)類型名稱占用存儲空間表數(shù)范圍默認(rèn)值byte字節(jié)8bit(即1個字節(jié))-128~127(-2^7~2^7-1)0short短整型16bit(即2個字節(jié))-32768~32717(-2^15~2^15-1)0int整型32bit(即4個字節(jié))-2^31~2^31-10long長整型64bit(即8個字節(jié))-2^63~2^63-10Lfloat單精度浮點型32bit(即4個字節(jié))-3.40E38~+3.40E380.0fdouble雙精度浮點型64bit(即8個字節(jié))-1.79E308~1.79E3080.0dchar字符型16bit(即2個字節(jié))0~65535‘\u0000’(空)boolean布爾類型8bit(即1個字節(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.保存類的實例,即堆區(qū)對象的引用(指針)。也可以用來保存加載方法時的幀。

堆:用來存放動態(tài)產(chǎn)生的數(shù)據(jù),比如new出來的對象。注意創(chuàng)建出來的對象只包含屬于各自的成員變量,并不包括成員方法。因為同一個類的對象擁有各自的成員變量,存儲在各自的堆中,但是他們共享該類的方法,并不是每創(chuàng)建一個對象就把成員方法復(fù)制一次。常量池:JVM為每個已加載的類型維護(hù)一個常量池,常量池就是這個類型用到的常量的一個有序集合。包括直接常量(基本類型,String)和對其他類型、方法、字段的符號引用。池中的數(shù)據(jù)和數(shù)組一樣通過索引訪問。由于常量池包含了一個類型所有的對其他類型、方法、字段的符號引用,所以常量池在Java的動態(tài)鏈接中起了核心作用。常量池存在于堆中。三個關(guān)鍵存儲運(yùn)行時數(shù)據(jù)的地方(棧,堆,常量池)一:在方法中聲明的變量,即該變量是局部變量,每當(dāng)程序調(diào)用方法時,系統(tǒng)都會為該方法建立一個方法棧,其所在方法中聲明的變量就放在方法棧中,當(dāng)方法結(jié)束系統(tǒng)會釋放方法棧,其對應(yīng)在該方法中聲明的變量隨著棧的銷毀而結(jié)束,這就局部變量只能在方法中有效的原因

在方法中聲明的變量可以是基本類型的變量,也可以是引用類型的變量。

(1)當(dāng)聲明是基本類型的變量的時,其變量名及值(變量名及值是兩個概念)是放在JAVA虛擬機(jī)棧中

(2)當(dāng)聲明的是引用(變量時,所聲明的變量(該變量實際上是在方法中存儲的是內(nèi)存地址值)是放在 JAVA虛擬機(jī)的棧中,該變量所指向的對象是放在堆類存中的。二:在類中聲明的變量是成員變量,也叫全局變量,放在堆中的(因為全局變量不會隨著某個方法執(zhí)行結(jié)束而銷毀)。

同樣在類中聲明的變量即可是基本類型的變量也可是引用類型的變量

(1)當(dāng)聲明的是基本類型的變量其變量名及其值放在堆內(nèi)存中的

(2)引用類型時,其聲明的變量仍然會存儲一個內(nèi)存地址值,該內(nèi)存地址值指向所引用的對象。引用變

量名和對應(yīng)的對象仍然存儲在相應(yīng)的堆中。java中的基本數(shù)據(jù)類型一定存儲在棧中的嗎?錯基本數(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í)行時候的變化:

1.main方法開始執(zhí)行:intdate=9;

date局部變量,基礎(chǔ)類型,引用和值都存在棧中。

2.Testtest=newTest();

test為對象引用,存在棧中,對象(newTest())存堆中。

3.test.change(date);

i為局部變量,引用和值存在棧中。當(dāng)方法change執(zhí)行完

成后,i就會從棧中消失。

4.BirthDated1=newBirthDate(7,7,1970);

d1為對象引用,存在棧中,對象(newBirthDate())存在堆中,其中d,m,y為局部變量存儲在棧中,且它們的類型為基礎(chǔ)類型,因此它們的數(shù)據(jù)也存儲在棧中。day,month,year為成員變量,它們存儲在堆中(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ù)據(jù)區(qū))JavaVirtualMachine方法區(qū)MethodAreaJavaRuntimeAreaJava運(yùn)行時數(shù)據(jù)區(qū)Java虛擬機(jī)棧JavaStackJava本地方法棧NativeMethodStackJava堆Heap程序計數(shù)器ProgramCounterRegister每個線程對象獨享所有線程對象共享棧(JavaStack):又叫堆棧。JVM為每個新創(chuàng)建的線程都分配一個棧。也就是說,對于一個Java程序來說,它的運(yùn)行就是通過對棧的操作來完成的。棧以幀為單位保存線程的狀態(tài)。JVM對棧只進(jìn)行兩種操作:以幀為單位的壓棧和出棧操作。我們知道,某個線程正在執(zhí)行的方法稱為此線程的當(dāng)前方法。我們可能不知道,當(dāng)前方法使用的幀稱為當(dāng)前幀。當(dāng)線程激活一個Java方法,JVM就會在線程的Java堆棧里新壓入一個幀,這個幀自然成為了當(dāng)前幀。在此方法執(zhí)行期間,這個幀將用來保存參數(shù)、局部變量、中間計算過程和其他數(shù)據(jù)。從Java的這種分配機(jī)制來看,堆棧又可以這樣理解:棧(Stack)是操作系統(tǒng)在建立某個進(jìn)程時或者線程(在支持多線程的操作系統(tǒng)中是線程)為這個線程建立的存儲區(qū)域,該區(qū)域具有先進(jìn)后出的特性。其相關(guān)設(shè)置參數(shù):-Xss–設(shè)置方法棧的最大值本地方法棧(NativeMethodStack):存儲本地方方法的調(diào)用狀態(tài)。程序計數(shù)器(ProgramCountRegister):又叫程序寄存器。JVM支持多個線程同時運(yùn)行,當(dāng)每一個新線程被創(chuàng)建時,它都將得到它自己的PC寄存器(程序計數(shù)器)。如果線程正在執(zhí)行的是一個Java方法(非native),那么PC寄存器的值將總是指向下一條將被執(zhí)行的指令,如果方法是native的,程序計數(shù)器寄存器的值不會被定義。JVM的程序計數(shù)器寄存器的寬度足夠保證可以持有一個返回地址或者native的指針。堆(Heap):Java堆(JavaHeap)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域。在此區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例都是在這里分配內(nèi)存,但是這個對象的引用卻是在棧(Stack)中分配。比如,執(zhí)行Strings=newString(“s”)時,需要從兩個地方分配內(nèi)存:在堆中為String對象分配內(nèi)存,在棧中為引用(這個堆對象的內(nèi)存地址,即指針)。線程這里所說的線程指程序執(zhí)行過程中的一個線程實體。JVM允許一個應(yīng)用并發(fā)執(zhí)行多個線程。HotspotJVM中的Java線程與原生操作系統(tǒng)線程有直接的映射關(guān)系。當(dāng)線程本地存儲、緩沖區(qū)分配、同步對象、棧、程序計數(shù)器等準(zhǔn)備好以后,就會創(chuàng)建一個操作系統(tǒng)原生線程。Java線程結(jié)束,原生線程隨之被回收。操作系統(tǒng)負(fù)責(zé)調(diào)度所有線程,并把它們分配到任何可用的CPU上。當(dāng)原生線程初始化完畢,就會調(diào)用Java線程的run()方法。run()返回時,被處理未捕獲異常,原生線程將確認(rèn)由于它的結(jié)束是否要終止JVM進(jìn)程(比如這個線程是最后一個非守護(hù)線程)。當(dāng)線程結(jié)束時,會釋放原生線程和Java線程的所有資源。JVM系統(tǒng)線程如果使用jconsole或者其它調(diào)試器,你會看到很多線程在后臺運(yùn)行。這些后臺線程與觸發(fā)publicstaticvoidmain(String[])函數(shù)的主線程以及主線程創(chuàng)建的其他線程一起運(yùn)行。HotspotJVM后臺運(yùn)行的系統(tǒng)線程主要有右面幾個:虛擬機(jī)線程(VMthread這個線程等待JVM到達(dá)安全點操作出現(xiàn)。這些操作必須要在獨立的線程里執(zhí)行,因為當(dāng)堆修改無法進(jìn)行時,線程都需要JVM位于安全點。這些操作的類型有:stop-the-world垃圾回收、線程棧dump、線程暫停、線程偏向鎖(biasedlocking)解除。周期性任務(wù)線程這線程負(fù)責(zé)定時器事件(也就是中斷),用來調(diào)度周期性操作的執(zhí)行。GC線程這些線程支持JVM中不同的垃圾回收活動。編譯器線程這些線程在運(yùn)行時將字節(jié)碼動態(tài)編譯成本地平臺相關(guān)的機(jī)器碼。信號分發(fā)線程這個線程接收發(fā)送到JVM的信號并調(diào)用適當(dāng)?shù)腏VM方法處理。線程一線程三線程二PC寄存器棧幀棧幀棧幀棧幀棧幀棧幀棧幀線程三Java棧本地方法棧線程一線程三線程二棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)棧幀(StackFrame)局部變量表操作數(shù)棧指向運(yùn)行時常量的引用方法返回地址動態(tài)鏈接棧頂(當(dāng)前方法)(StackFrame)Java虛擬機(jī)棧(JavaVirtualMachineStacks)1.棧內(nèi)存是線程共有的,其生命周期與線程相同。2.虛擬機(jī)描述的是Java方法執(zhí)行的內(nèi)存模型:執(zhí)行一個方法會產(chǎn)生一個棧幀,隨后將其保存到棧(后進(jìn)先出)的頂部,方法執(zhí)行完畢后會自動將此棧幀進(jìn)行出棧。頂部的棧幀表示的就是當(dāng)前的方法。如果請求的棧的深度過大,虛擬機(jī)可能會拋出StackOverflowError異常如果虛擬機(jī)的實現(xiàn)中允許,虛擬機(jī)棧動態(tài)擴(kuò)展,當(dāng)內(nèi)存不足以擴(kuò)展棧的時候,會拋出OutOfMemory異常。局部變量表(LocalVariables):方法的局部變量或形參,其以變量槽(solt)為最小單位,只允許保存32位長度的變量,如果超過32位則會開辟兩個連續(xù)的solt(64位,long和double)。操作數(shù)棧(OperandStack):表達(dá)式計算在棧中完成。指向當(dāng)前方法所屬的類的運(yùn)行時常量池的引用(ReferencetoRuntimeConstantPool):引用其他類的常量或者使用String池中的字符串。方法返回地址(ReturnAddress):方法執(zhí)行完成后需要返回調(diào)用此方法的位置,所以需要在棧中保存方法的返回地址。動態(tài)鏈接(dynamiclinking):每個棧幀都有一個運(yùn)行時常量池的引用。這個引用指向棧幀當(dāng)前運(yùn)行方法所在類的常量池。通過這個引用支持動態(tài)鏈接(dynamiclinking)。C/C++代碼一般被編譯成對象文件,然后多個對象文件被鏈接到一起產(chǎn)生可執(zhí)行文件或者dll。在鏈接階段,每個對象文件的符號引用被替換成了最終執(zhí)行文件的相對偏移內(nèi)存地址。在Java中,鏈接階段是運(yùn)行時動態(tài)完成的。當(dāng)Java類文件編譯時,所有變量和方法的引用都被當(dāng)做符號引用存儲在這個類的常量池中。符號引用是一個邏輯引用,實際上并不指向物理內(nèi)存地址。JVM可以選擇符號引用解析的時機(jī),一種是當(dāng)類文件加載并校驗通過后,這種解析方式被稱為饑餓方式。另外一種是符號引用在第一次使用的時候被解析,這種解析方式稱為惰性方式。無論如何,JVM必須要在第一次使用符號引用時完成解析并拋出可能發(fā)生的解析錯誤。綁定是將對象域、方法、類的符號引用替換為直接引用的過程。綁定只會發(fā)生一次。一旦綁定,符號引用會被完全替換。如果一個類的符號引用還沒有被解析,那么就會載入這個類。每個直接引用都被存儲為相對于存儲結(jié)構(gòu)(與運(yùn)行時變量或方法的位置相關(guān)聯(lián)的)偏移量。運(yùn)行時常量池堆數(shù)據(jù)類型數(shù)字型字符串型類引用型域引用型方法引用數(shù)據(jù)類型對象(實例)數(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個字節(jié)用于存儲魔數(shù)MagicNumber,用于確定一個文件是否能被JVM接受,再接著4個字節(jié)用于存儲版本號,前2個字節(jié)存儲次版本號,后2個存儲主版本號,再接著是用于存放常量的常量池,由于常量的數(shù)量是不固定的,所以常量池的入口放置一個U2類型的數(shù)據(jù)(constant_pool_count)存儲常量池容量計數(shù)值。

常量池主要用于存放兩大類常量:字面量(Literal)和符號引用量(SymbolicReferences),字面量相當(dāng)于Java語言層面常量的概念,如文本字符串,聲明為final的常量值等,符號引用則屬于編譯原理方面的概念,包括了如下三種類型的常量:類和接口的全限定名字段名稱和描述符方法名稱和描述符詳細(xì)請看連接:/p/c7f47de2ee80Integer4字節(jié)常量Long8字節(jié)常量Float4字節(jié)常量Double8字節(jié)常量String字符串常量指向常量池的另外一個包含真正字節(jié)Utf8編碼的實體Utf8Utf8編碼的字符序列字節(jié)流Class一個Class常量,指向常量池的另一個Utf8實體,這個實體包含了符合JVM內(nèi)部格式的類的全名(動態(tài)鏈接過程需要用到)NameAndType冒號(:)分隔的一組值,這些值都指向常量池中的其它實體。第一個值(“:”之前的)指向一個Utf8字符串實體,它是一個方法名或者字段名。第二個值指向表示類型的Utf8實體。對于字段類型,這個值是類的全名,對于方法類型,這個值是每個參數(shù)類型類的類全名的列表。Fieldref,Methodref,InterfaceMethodref點號(.)分隔的一組值,每個值都指向常量池中的其它的實體。第一個值(“.”號之前的)指向類實體,第二個值指向NameAndType實體。這個常量池包含了下面的類型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)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論