1. java把內存劃分成兩種:一種是棧內存,一種是堆內存。請分別解釋二者的含義,並說明有何區別
(1) 堆棧。駐留於常規RAM(隨機訪問存儲器)區域,但可通過它的「堆棧指針」獲得處理的直接支持。堆棧指針若向下移,會創建新的內存;若向上移,則會釋放那些內存。這是一種特別快、特別有效的數據保存方式,僅次於寄存器。創建程序時,Java編譯器必須准確地知道堆棧內保存的所有數據的「長度」以及「存在時間」。這是由於它必須生成相應的代碼,以便向上和向下移動指針。這一限制無疑影響了程序的靈活性,所以盡管有些Java數據要保存在堆棧里——特別是對象句柄,但Java對象並不放到其中。
(2) 堆。一種常規用途的內存池(也在RAM區域),其中保存了Java對象。和堆棧不同,「內存堆」或「堆」(Heap)最吸引人的地方在於編譯器不必知道要從堆里分配多少存儲空間,也不必知道存儲的數據要在堆里停留多長的時間。因此,用堆保存數據時會得到更大的靈活性。要求創建一個對象時,只需用new命令編制相關的代碼即可。執行這些代碼時,會在堆里自動進行數據的保存。當然,為達到這種靈活性,必然會付出一定的代價:在堆里分配存儲空間時會花掉更長的時間!
(3) 靜態存儲。這兒的「靜態」(Static)是指「位於固定位置」(盡管也在RAM里)。程序運行期間,靜態存儲的數據將隨時等候調用。可用static關鍵字指出一個對象的特定元素是靜態的。但Java對象本身永遠都不會置入靜態存儲空間。
2. 如何理解java中的堆與棧
Java 把內存劃分成兩種:一種是棧內存,另一種是堆內存。在函數中定義的一些基本類型的變數和對象的引用變數都是在函數的棧內存中分配,當在一段代碼塊定義一個變數時,Java 就在棧中為這個變數分配內存空間,當超過變數的作用域後,Java 會自動釋放掉為該變數分配的內存空間,該內存空間可以立即被另作它用。
3. 在java編寫的程序中,棧內存跟堆內存分別存儲的是什麼呢
你只需要知道兩點
一
堆中存放具體數據
棧中存放你所命名的變數名字
二
既然叫匿名函數
自然沒有名字
所以這就是在堆里有具體數據
而棧中沒有名字指向這個數據的意思
4. java中的堆內存和棧內存分別存放什麼東西
其實JAVA的內存模型更復雜一些的,既然你這么問,那我簡單的來回答一下:
一般占內存是放方法,臨時變數等,堆內存在JAVA裡面主要是放置生成的對象的
5. java中 關於常量池 棧內存 堆內存
Java中所有局部變數和對象的引用都是存儲在棧內存中的,int a = 1;它是局部變數肯定是在棧內存,但是它與常量池沒有關系;
常量池是堆內存中的一部分,專門用來存儲字元串常量;所以String a="abc"中,引用a是存儲在棧內存的,指向常量池中的"abc";
但是如果是String a = new String("abc");就又不一樣了,對於通過構造函數得到的"abc"字元串對象,引用a還是在棧內存,但是"abc"不會存到字元串常量池中,而是在常量池之外的其他堆內存中再生成一個"abc",由於這個對象與原先常量池中的"abc"對象是equal關系,它們之間會建立起一種聯系;
6. java中堆和棧內存的區別
棧內存:
在函數中定義的一些基本類型的變數和對象的引用變數都在函數的棧內存中分配。棧內存主要存放的是基本類型類型的數據 如( int, short, long, byte, float, double, boolean, char) 和對象句柄。注意:並沒有String基本類型、在棧內存的數據的大小及生存周期是必須確定的、其優點是寄存速度快、棧數據可以共享、缺點是數據固定、不夠靈活。
棧的共享:
String str1 = "myString"; String str2 = "myString"; System.out.println(str1 ==str2 ); //注意:這里使用的是str1 ==str2,而不是str1.equals(str2)的方式。 //因為根據JDK的說明,==號只有在兩個引用都指向了同一個對象時才返回真值 //而str1.equals(str2),只是比較兩個字元串是否相等
結果為True,這就說明了str1和str2其實指向的是同一個值。
上述代碼的原理是,首先在棧中創建一個變數為str1的引用,然後查找棧中是否有myString這個值,如果沒找到,就將myString存放進來,然後將str1指向myString。接著處理String str2 = "myString";;在創建完str2 的引用變數後,因為在棧中已經有myString這個值,便將str2 直接指向myString。這樣,就出現了str1與str2 同時指向myString。
特別注意的是,這種字面值的引用與類對象的引用不同。假定兩個類對象的引用同時指向一個對象,如果一個對象引用變數修改了這個對象的內部狀態,那麼另一個對象引用變數也即刻反映出這個變化。相反,通過字面值的引用來修改其值,不會導致另一個指向此字面值的引用的值也跟著改變的情況。如上例,我們定義完str1與str2 的值後,再令str1=yourString;那麼,str2不會等於yourString,還是等於myString。在編譯器內部,遇到str1=yourString;時,它就會重新搜索棧中是否有yourString的字面值,如果沒有,重新開闢地址存放yourString的值;如果已經有了,則直接將str1指向這個地址。因此str1值的改變不會影響到str2的值。
堆內存:
堆內存用來存放所有new 創建的對象和 數組的數據
String str1 = new String ("myString"); String str2 = "myString"; System.out.println(str1 ==str2 ); //False String str1 = new String ("myString"); String str2 = new String ("myString"); System.out.println(a==b); //False
創建了兩個引用,創建了兩個對象。兩個引用分別指向不同的兩個對象。以上兩段代碼說明,只要是用new()來新建對象的,都會在堆中創建,而且其字元串是單獨存值的,即使與棧中的數據相同,也不會與棧中的數據共享。
7. 在Java里堆內存和棧內存有什麼區別
這個來自於古老的C語言概念,凡是在函數中用基本數據類型(string除外)申請的局部變數,也就是函數退出則這些變數就消亡的變數,包括函數自己的參數定義,都用棧內存的方式構造內存,這樣做的目的是進入該函數、變數值進棧,函數退出自動退棧,這樣就自動完成了內存申請和回收,這些棧空間的變數只能被該函數自己引用,其他函數不能引用。
而C語言的全局變數、JAVA的對象,也就是說如C語言用malloc()函數,C++、JAVA等用new構造的對象,都在堆方式組織的內存中,這樣的目的是讓很多函數都能引用到這些存儲空間的值或者對象。存儲在堆空間的對象和數據,需要編程者按需要釋放,如C語言用free(),C++則要析構函數,Java就有自動回收機制。
隨手寫的,有錯勿噴。
8. 如何理解java的堆內存和棧內存
1 棧:為編譯器自動分配和釋放,如函數參數、局部變數、臨時變數等等
2 堆:為成員分配和釋放,由程序員自己申請、自己釋放。否則發生內存泄露。典型為使用new申請的堆內容。
9. Java中棧內存和堆內存怎麼理解
Object
obj
=
new
Object();
以上這句話,會把obj這個引用放進棧內存,再說白一點,就是這個對象的名字obj放進棧內存,棧內存運行速度較快,用於查找索引(也就是名字)
而new
Object()會在堆內存中開辟一塊空間給這個對象,對象幾乎所有的屬性啊,方法啊,全都在裡面了,也就是對象的實體都在堆內存中
,堆內存速度慢但是成本低,空間較大,用以存放程序
10. java中堆內存如何釋放
java把內存分成兩種,一種叫做棧內存,一種叫做堆內存
在函數中定義的一些基本類型的變數和對象的引用變數都是在函數的棧內存中分配。當在一段代碼塊中定義一個變數時,java就在棧中為這個變數分配內存空間,當超過變數的作用域後,java會自動釋放掉為改變數分配的內存空間,該內存空間可以立刻被另作他用。
堆內存用於存放由new創建的對象和數組。在堆中分配的內存,由java虛擬機自動垃圾回收器來管理。在堆中產生了一個數組或者對象後,還可以在
棧中定義一個特殊的變數,這個變數的取值等於數組或者對象在堆內存中的首地址,在棧中的這個特殊的變數就變成了數組或者對象的引用變數,以後就可以在程序
中使用棧內存中的引用變數來訪問堆中的數組或者對象,引用變數相當於為數組或者對象起的一個別名,或者代號。
引用變數是普通變數,定義時在棧中分配內存,引用變數在程序運行到作用域外釋放。而數組&對象本身在堆中分配,即使程序運行到使用new產生數組
和對象的語句所在地代碼塊之外,數組和對象本身佔用的堆內存也不會被釋放,數組和對象在沒有引用變數指向它的時候,才變成垃圾,不能再被使用,但是仍然占
著內存,在隨後的一個不確定的時間被垃圾回收器釋放掉。這個也是java比較占內存的主要原因。但是在寫程序的時候,可以人為的控制。