Java中对象的储存区
文章目錄
- 1 兩個(gè)重要的問(wèn)題
- 2 C語(yǔ)言中數(shù)據(jù)的存儲(chǔ)區(qū)
- 3 Java中對(duì)象的儲(chǔ)存區(qū)
- 4 Java為什么采用動(dòng)態(tài)內(nèi)存分配?
- 4 為什么基本類(lèi)型是特例?
1 兩個(gè)重要的問(wèn)題
對(duì)象的數(shù)據(jù)位于何處?
如何控制對(duì)象的生命周期?
2 C語(yǔ)言中數(shù)據(jù)的存儲(chǔ)區(qū)
棧內(nèi)存(Stack):主要是用來(lái)存儲(chǔ)函數(shù)調(diào)用(function calls)和局部變量(local variables) 的內(nèi)存區(qū),它在內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)本質(zhì)就是一個(gè)棧(Stack)。需要注意的是,如果棧內(nèi)存使用過(guò)多,就會(huì)出現(xiàn)所謂的堆棧溢位(Stack overflow),如死遞歸。
堆內(nèi)存(Heap):主要是用來(lái)存儲(chǔ)由 malloc() 申請(qǐng)的內(nèi)存。如果 malloc() 返回**NULL**的話(huà)就表明內(nèi)存用完。
靜態(tài)內(nèi)存(Static):它的生命周期與程序相同,即在進(jìn)程創(chuàng)建是被創(chuàng)建,在程序退出時(shí)被銷(xiāo)毀。全局作用域變量(global variables), 文件作用域變量(file scope variables)和被 static 修飾的變量會(huì)儲(chǔ)存在這里。
寄存器(Register):這個(gè)關(guān)鍵字的作用是請(qǐng)求編譯器盡可能的將變量存在CPU內(nèi)部寄存器中,而不是通過(guò)內(nèi)存尋址訪(fǎng)問(wèn),以提高效率。需要注意的是:register這個(gè)關(guān)鍵字只是一個(gè)請(qǐng)求,請(qǐng)求CPU給你一個(gè)內(nèi)存,給不給還在于CPU。
3 Java中對(duì)象的儲(chǔ)存區(qū)
棧:通過(guò)堆棧指針來(lái)操縱內(nèi)存,指針下移則分配內(nèi)存,指針上移則釋放內(nèi)存, 如圖(圖片來(lái)源于網(wǎng)絡(luò))
在程序創(chuàng)建的時(shí)候,必須知道儲(chǔ)存在堆棧內(nèi)所有的數(shù)據(jù)項(xiàng),以便可以操縱指針,這樣的約束就限制了Java的靈活性,所以部分?jǐn)?shù)據(jù)存儲(chǔ)在此,特別是對(duì)象的引用,而對(duì)象本身不儲(chǔ)存并在其中。
堆:用于存放所有的Java對(duì)象,不同于棧,它不需要知道數(shù)據(jù)在堆中的生存期,需要的時(shí)候便 new 一個(gè)對(duì)象出來(lái),那么如何釋放掉內(nèi)存呢?不得不提的是Java中的垃圾回收機(jī)制了,不像C/C++需要手動(dòng)釋放內(nèi)存,垃圾回收機(jī)制會(huì)自動(dòng)地檢測(cè)并釋放無(wú)用的內(nèi)存,避免了程序的內(nèi)存泄漏問(wèn)題。
常量?jī)?chǔ)存:常量值一般直接存放在程序代碼的內(nèi)部,這樣做是很安全的,因?yàn)槭浅A恐?#xff0c;所以他們不希望被改變,也不會(huì)被改變。
寄存器:(編程人員不能控制,也感知不到,不做討論)
非RAM儲(chǔ)存:儲(chǔ)存在磁盤(pán)上的對(duì)象。
4 Java為什么采用動(dòng)態(tài)內(nèi)存分配?
C/C++認(rèn)為效率的控制是很重要的,那么在設(shè)計(jì)者在實(shí)現(xiàn)的時(shí)候給予了編程人員選擇的權(quán)力,為了追求更快的速度和更高的效率,對(duì)象的存儲(chǔ)空間和生命周期在編寫(xiě)程序的時(shí)候就確定,這種方式將存儲(chǔ)空間的分配和釋放放置于優(yōu)先考慮的位置,但是某些情況這種方式也犧牲了靈活性,于是就有第二種方式。
第二種存儲(chǔ)方式就是在堆內(nèi)存中動(dòng)態(tài)的創(chuàng)建,這種方式中,直到運(yùn)行程序的時(shí)候才知道需要多少對(duì)象,才知道它們的生命周期及其屬性,在需要的時(shí)候也可以在此時(shí)刻創(chuàng)建,即儲(chǔ)存空間是動(dòng)態(tài)管理的,但是這種方式需要花費(fèi)大量的時(shí)間在堆中分配存儲(chǔ)空間即釋放內(nèi)存空間,這可能要遠(yuǎn)遠(yuǎn)大于在堆棧中創(chuàng)建儲(chǔ)存空間的時(shí)間,在堆棧中創(chuàng)建儲(chǔ)存空間和釋放儲(chǔ)存空間各需要一條匯編指令即可。
所以Java設(shè)計(jì)者認(rèn)為動(dòng)態(tài)操作的方式雖然速度效率不及前者,但是在復(fù)雜的程序設(shè)計(jì)中,這種靈活方式反而提升了速度和效率,所以Java完全采用了動(dòng)態(tài)內(nèi)存分配方式(基本類(lèi)型是特例)。
4 為什么基本類(lèi)型是特例?
Java中的基本類(lèi)型:
boolean、byte、char、short、int、long、float、double、(void)
如果基本類(lèi)型往往是特別小而簡(jiǎn)單的變量,如果 new 一個(gè)對(duì)象出來(lái),并不具有效率。
所以和C/C++一樣,Java對(duì)待基本變量,把它儲(chǔ)存在堆棧中,更具有效率。
為了讓基本類(lèi)型具有變量的特性,Java中也有相應(yīng)的包裹類(lèi)型,來(lái)應(yīng)對(duì)不同的需求:
| boolean | Boolean |
| byte | Byte |
| char | Character |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| void | Void |
參考:
《Thinking in Java》 - Bruce Eckel
總結(jié)
以上是生活随笔為你收集整理的Java中对象的储存区的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C语言-链表的创建头插法和尾插法(有无头
- 下一篇: 什么是补码,怎么求补码