P46頁有感java
寄存器位於CPU內部,這是計算機硬件中處理速度最快的地方,是真正的處理程序的位置。寄存器是由編譯器根據須要來分配的,而且即使是編譯器,也須要經過操做系統的搶佔式調度纔可以得到CPU的處理權,所以,寄存器的存儲空間時很是有限的,開發人員對寄存器沒有直接的控制權,在程序裏也無法對寄存器有什麼操做。程序員
堆棧通常也叫棧,通常指的是RAM區域,處理速度僅次於寄存器。在堆棧中,通常存放的都是對象的引用,當棧指針下移的時候,就建立新的內存,反之則釋放內存。當建立一個對象時。該對象的會被放到堆內存的空間,而該對象的引用則會被放到棧內存中。而且Java 編譯器必須準確地知道堆棧內保存的全部數據的「長度」以及「存
在時間」。以便回收空間和知道棧內存還剩餘多少空間。編程
堆內存也是在RAM區域,它是對象的真正存放位置,當new一個對象時,該對象就會被存放至堆內存,而且Java編譯器不須要去在乎堆中還剩多少空間,Java 有一個特別 的「垃圾收集器」,它會查找用new建立的全部對象,並辨別其中哪些再也不被引用。隨後,它會自動釋放由 那些閒置對象佔據的內存,以便能由新對象使用。這意味着咱們根本沒必要操心內存的回收問題。只需簡單地建立對象,一旦再也不須要它們,它們就會自動離去。這樣作可防止在C++裏很常見的一個編程問題:因爲程序員忘記釋放內存形成的「內存溢出」,對象的銷燬---對象的引用放在棧中,因此使用完引用就被從棧中銷燬了,可是實際的對象仍然存放在堆中,只有在沒有任何的引用使用它的時候才被垃圾回收器銷燬掉。安全
class StaticTest { Static int i = 47; } //如今咱們 new兩個對象 StaticTest st1 = new StaticTest(); StaticTest st2 = new StaticTest(); //st1.i和st2.i都是47 儘管咱們製做了兩個StaticTest對象,但它們仍然只佔據StaticTest.i的一個存儲空間。這兩個對象都共享一樣的i 此時不論是哪一個對象執行st1++,另外一個對象的i也會加一
常數存儲。常數值一般直接置於程序代碼內部。這樣作是安全的,由於它們永遠都不會改變。有的常數 須要嚴格地保護,因此可考慮將它們置入ROM。學習
非RAM存儲。若數據徹底獨立於一個程序以外,則程序不運行時仍可存在,並在程序的控制範圍以外。 其中兩個最主要的例子即是「流式對象」和「固定對象」。對於流式對象,對象會變成字節流,一般會發給 另外一臺機器。而對於固定對象,對象保存在磁盤中。即便程序停止運行,它們仍可保持本身的狀態不變。對 於這些類型的數據存儲,一個特別有用的技巧就是它們能存在於其餘媒體中。一旦須要,甚至能將它們恢復 成普通的、基於RAM的對象。Java 1.1提供了對Lightweight persistence的支持。將來的版本甚至可能提 供更完整的方案。操作系統
在Java編程思想中對於基本數據類型的存儲位置有這麼一句話線程
對於這些基本類型,Java 採納了與C和C++相同的方法。也就是說,不是用 new建立變量,而是建立一個並不是引用的「自動」變量。這個變量容納了具體的值,並置於堆棧中,可以更 高效地存取。指針
可是我百度查找了一些相關資料,也有說基本數據類型有放在堆中的。梳理一下,首先,八大基本類型都不能看作對象,基本類型的存儲位置要分狀況,當基本類型的建立是在類中。像這樣code
class Demo{ int a = 1;//狀況1 public int test(){ int b = 2;//狀況2 } }
在狀況1下,建立的是全局變量。是隨着對象一塊兒存放在堆中的,在狀況2下,建立的是局部變量,每當程序調用方法時,系統都會爲該方法創建一個方法棧,其所在方法中聲明的變量就放在方法棧中,當方法結束系統會釋放方法棧,其對應在該方法中聲明的變量隨着棧的銷燬而結束,這就局部變量只能在方法中有效的緣由。因而可知,基本類型並非徹底存儲在棧區的。緣由是由於,上面基礎知識提到的,堆是全部線程共享的內存區域,棧 是每一個線程獨享的。若是你將一個實例變量放在棧內,那麼就不存在多個線程訪問同一個對象資源了,這顯然是不對的,因此全局變量要在堆上建立,也不是線程安全的。可是對於局部變量,是在棧上建立的,每一次方法調用建立一個方法棧,獨享一分內存區域,其餘的線程是不會訪問到該線程的資源,在 棧上建立也會減輕GC的壓力,隨着該方法的結束,相對應的方法棧內存消除,這種局部變量佔用的內存天然就消失了,所以局部變量是線程安全的。對象