java 基本功 —— 内存相关
2019獨角獸企業重金招聘Python工程師標準>>>
首先我們來說說內存,因為從內存的角度來出發來分析一些變量,引用或者對象的生命周期會更好理解一些。
java是一門編程語言,他跟C++有什么不同呢?本質上,他們都是一樣的,殊途同歸。因為底層都是操作內存和磁盤的工具,只是語法不同,表現形式不同而已。
所以有的時候不必刨根問底,因為這可能只是語言的一種規則而已。
java中都是以對象和對象的引用形式來操作數據的,那么java中是如何分配這些存儲引用和內存的呢?
?
一、 java 中的內存塊
1. 寄存器。這是最快的存儲區,以為它位于不同于其他存儲區的地方——處理器內部。但是寄存器的數量極其有限,所以寄存器根據需求進行分配。你不能直接控制,也不能在程序中感覺到寄存器存在的任何跡象。
2. 棧(又名堆棧),原型就是碟盤子模型,先放的盤子后拿。棧位于通用RAM(隨機訪問存儲器)中,但通過堆棧指針可以直接從處理器那里獲得直接支持。通過棧頂指針的上下移動來創建和釋放內存,這是一種快速有效的分配存儲的方法,僅次于寄存器。但是這種方式,java系統必須知道存儲在堆棧內所有項的生命周期,以便上下移動堆棧指針。所以對象的引用存在與堆棧中(因為由確切的生命周期),但是對象不會存于堆棧中(無確切的生命周期)。
3.堆。一種通用的內存池,也是位于RAM區,用于存放所有的java對象。堆不同與堆棧的好處是:編譯器不需要知道存儲的數據在堆里存活多長時間。因此,在堆里分配存儲由很大的靈活性。當需要一個對象時,只需new一個,當執行時,會自動在堆里進行分配內存。當然,為了這種靈活性必須付出相應的代價:用堆進行存儲分配和清理可能比用堆棧進行存儲分配需要更多的時間。(對比于C++,對象會在棧中存儲,因為對象的生命周期都是程序員自己控制的)
4.常量存儲。常量值通常直接存放在程序代碼的內部。
5.非RAM存儲。如果數據完全存活于程序之外,那么可以不受程序的任何控制,在程序沒有運行時也可以存在。其中兩個基本的例子就是流對象和持久化對象。在流對象中,對象轉化成字節流,通常被發送給另一臺機器。在持久化對象中,對象被存放于磁盤上,因此,即使程序終止,他們仍可以保持自己的狀態。這種存儲方式的技巧在于:把對象轉化成為可以存儲在其他媒介上的事物,在需要時,可恢復成常規的、基于RAM的對象。java提供了對輕量級持久化的支持。
二、基本類型在棧中
java對于小的,基本的變量是這樣處理的:
將他們固定長度,直接存儲值于堆棧中,所以java的基本類型都是有固定取值范圍的。
java基本類型長度不變也是java的可移植性的重要原因。
三、對象的生命周期
變量的生命周期往往是由大括號決定的,而對象則不然
{
??? String s = new String("a? string");
}
在上面的這段代碼中,引用s在作用域終點就消失了。然而,s指向的String對象仍然繼續占據著內存空間。
我們已經無法在作用與之外訪問這個對象,因為他唯一的引用已經失效了。
事實證明,由new創建的對象,只要你需要,就會一直保留下去。
那么他們什么時候消亡,以至于不會填滿內存呢?這就引出了垃圾回收器。
垃圾回收器的作用:監視new創建的所有對象,并辨識哪些對象是不會再被引用的對象,隨后,釋放這些對象的內存空間,以便供其他新的對象使用。所以對象不需要程序員自己回收。神奇的GC...
三、有關static
class StaticTest {
??? static int i = 47;
}
即使你創建了兩個StaticTest對象,StaticTest.i也只有一份存儲空間,這兩個對象共享一個i。
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
在這里,st1.i和 st2.i指向同一存儲空間,因此他們具有相同的值47.
所以static字段對每個類來說只有一份存儲空間,而非static字段則是對每個對象有一個存儲空間。
?
轉載于:https://my.oschina.net/u/2561483/blog/707913
總結
以上是生活随笔為你收集整理的java 基本功 —— 内存相关的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在线编写php文件,php单文件版在线代
- 下一篇: day20 django