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