本文目錄一覽:
- 1、java中堆和堆棧有什麼區別
- 2、java 棧和堆 的區別
- 3、java中堆與棧的區別
- 4、java中堆和棧有什麼區別?
- 5、北大青鳥java培訓:堆和棧的區別?
- 6、java中堆和棧的區別主要在於
java中堆和堆棧有什麼區別
java中堆(heap)和堆棧(stack)有什麼區別 stack 和 heep 都是內存的一部分
stack 空間小,速度比較快, 用來放對象的引用
heep 大,一般所有創建的對象都放在這裡。
棧(stack):是一個先進後出的數據結構,通常用於保存方法(函數)中的參數,局部變數.
在java中,所有基本類型和引用類型都在棧中存儲.棧中數據的生存空間一般在當前scopes內(就是由{…}括起來的區域).
堆(heap):是一個可動態申請的內存空間(其記錄空閑內存空間的鏈表由操作系統維護),C中的malloc語句所產生的內存空間就在堆中.
在java中,所有使用new xxx()構造出來的對象都在堆中存儲,當垃圾回收器檢測到某對象未被引用,則自動銷毀該對象.所以,理論上說java中對象的生存空間是沒有限制的,只要有引用類型指向它,則它就可以在任意地方被使用.
1. 棧(stack)與堆(heap)都是Java用來在Ram中存放數據的地方。與C++不同,Java自動管理棧和堆,程序員不能直接地設置棧或堆。
2. 棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的寄存器。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。另外,棧數據可以共享,詳見第3點。堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由於要在運行時動態分配內存,存取速度較慢。
3. Java中的數據類型有兩種。
一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(注意,並沒有string的基本類型)。 這種類型的定義是通過諸如int a = 3; long b = 255L;的形式來定義的,稱為自動變數。值得注意的是,自動變數存的是字面值,不是類的實例,即不是類的引用,這裡並沒有類的存在。如int a = 3; 這裡的a是一個指向int類型的引用,指向3這個字面值。這些字面值的數據,由於大小可知,生存期可知(這些字面值固定定義在某個程序塊裡面,程序塊退出後,欄位值就消失了),出於追求速度的原因,就存在於棧中。
另外,棧有一個很重要的特殊性,就是存在棧中的數據可以共享。假設我們同時定義:
int a = 3;
int b = 3;
編譯器先處理int a = 3;首先它會在棧中創建一個變數為a的引用,然後查找有沒有字面值為3的地址,沒找到,就開闢一個存放3這個字面值的地址,然後將a指向3的地址。接著處理int b = 3;在創建完b的引用變數後,由於在棧中已經有3這個字面值,便將b直接指向3的地址。
這樣,就出現了a與b同時均指向3的情況。特別注意的是,這種字面值的引用與類對象的引用不同。
假定兩個類對象的引用同時指向一個對象,如果一個對象引用變數修改了這個對象的內部狀態,那麼另一個對象引用變數也即刻反映出這個變化。
相反,通過字面值的引用來修改其值,不會導致另一個指向此字面值的引用的值也跟著改變的情況。 如上例,我們定義完a與b的值後,再令a=4;那麼,b不會等於4,還是等於3。在編譯器內部,遇到a=4;時,它就會重新搜索棧中是否有4的字面值,如果沒有,重新開闢地址存放4的值;如果已經有了,則直接將a指向這個地址。因此a值的改變不會影響到b的值。
另一種是包裝類數據,如Integer, String, Double等將相應的基本數據類型包裝起來的類。這些類數據全部存在於堆中,Java用new()語句來顯示地告訴編譯器,在運行時才根據需要動態創建,因此比較靈活,但缺點是要佔用更多的時間。
4.String是一個特殊的包裝類數據。即可以用String str = new String(“abc”);的形式來創建,也可以用String str = “abc”;的形式來創建(作為對比,在JDK 5.0之前,你從未見過Integer i = 3;的表達式,因為類與字面值是不能通用的,除了String。而在JDK 5.0中,這種表達式是可以的!因為編譯器在後台進行Integer i = new Integer(3)的轉換!)。
前者是規範的類的創建過程,即在Java中,一切都是對象,而對象是類的實例,全部通過new()的形式來創建。Java中的有些類,如DateFormat類,可以通過該類的getInstance()方法來返回一個新創建的類,似乎違反了此原則。其實不然。該類運用了單例模式來返回類的實例,只不過這個實例是在該類內部通過new()來創建的,而getInstance()向外部隱藏了此細節。那為什麼在String str = “abc”;中,並沒有通過new()來創建實例,是不是違反了上述原則?其實沒有。
java 棧和堆 的區別
java堆和棧的區別Java中內存分成兩種:一種是棧stack,一種是堆heap。函數中的一些基本類型的變數(int,float)和對象的引用變數(reference)都在函數的棧中,馬克-to-win,(工作於編譯階段,生成class文件之前)分配。存取速度快,稍遜於寄存器,比堆快,函數執行完後,Java會自動釋放掉為函數里變數開闢的棧內存空間,該內存空間可以立即被另作他用。堆heap內存用來存放由new創建的對象和數組。堆內存,負責運行時(runtime,執行生成的class文件時)數據,由JVM的自動管理。缺點是,存取速度較慢。棧中的引用變數指向堆中的對象或數組。棧中有共享池的概念,比如下面例子中,sz=”hello”;在棧中創建一個String對象引用變數sz,然後看看棧中有沒有”hello”,如果沒有,則將”hello”存放進棧,並令sz指向」hello」,如果已經有」hello」則直接令sz指向「hello」。對於int,float類型的變數也是一樣的有這種共享池的概念,注意上述的工作是在compile(編譯)的階段完成的,而不是runtime運行時完成的。對於下面程序中:ss0=newString(“hello”);是用new()來新建對象的,存於堆中。每調用一次就會創建一個新的對象。當然從節省空間的角度來講,肯定不如str=”hello”,有童鞋一定問,那要它有什麼用?當時設計編譯器時,為什麼要設計它?馬克-to-win,那我請問你,如果在你編程序時,你還不知道字元串內容怎麼?這時就用到newString,所以,什麼都有什麼的用處。publicclassTest{publicstaticvoidmain(Stringargs[]){Stringstr,str1,ss0,ss1,ss2,ss3,ss4;str=”hello”;。。。。。。。。。。。。。。。。詳情網上找「馬克-to-win」,參考他的網站或他的百度空間:java第2章的內容
java中堆與棧的區別
Java的堆是一個運行時數據區,類的(對象從中分配空間。這些對象通過new、newarray、anewarray和multianewarray等
指令建立,它們不需要程序代碼來顯式的釋放。堆是由垃圾回收來負責的,堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時
動態分配內存的,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由於要在運行時動態分配內存,存取速度較慢。
棧的優勢是,存取速度比堆要快,僅次於寄存器,棧數據可以共享。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本類
型的變數(,int,
short,
long,
byte,
float,
double,
boolean,
char)和對象句柄。
java中堆和棧有什麼區別?
堆:(對象)
引用類型的變數,其內存分配在堆上或者常量池(字元串常量、基本數據類型常量),需要通過new等方式來創建。
堆內存主要作用是存放運行時創建(new)的對象。
(主要用於存放對象,存取速度慢,可以運行時動態分配內存,生存期不需要提前確定)
棧:(基本數據類型變數、對象的引用變數)
基本數據類型的變數(int、short、long、byte、float、double、boolean、char等)以及對象的引用變數,其內存分配在棧上,變數出了作用域就會自動釋放。
棧內存的主要作用是存放基本數據類型和引用變數。棧的內存管理是通過棧的”後進先出”模式來實現的。
(主要用來執行程序,存取速度快,大小和生存期必須確定,缺乏靈活性)
北大青鳥java培訓:堆和棧的區別?
棧:在編譯過程中分配的內存空間是由操作系統(編譯器)自動分配和釋放的,而堆棧上的空間是有限的。
在編譯過程中,程序在堆棧上同時為變數和函數分配內存,並且在堆棧上執行運行時函數調用的參數傳遞。
堆:在程序運行期間動態分配的內存空間,您可以根據程序運行的方式來確定要分配的堆內存的大小。
發行版通常由程序員分配。
內存函數的分配,如new和malloc,分配給堆。
棧是機器系統提供的數據結構,堆由C/c++函數庫提供。
棧是系統提供的功能,其特點是快速高效,缺點是有限的,數據不靈活;該堆棧是函數庫的函數,具有靈活性和方便性的特點,數據被廣泛使用,但效率可以降低。
棧是系統數據結構,它是流程/線程的唯一。
堆是函數庫的內部數據結構,不一定是唯一的。
不同堆分配的內存不能相互操作。
堆棧空間有兩種靜態分布和動態分配。
靜態分配由編譯器完成,例如自動變數(自動)分布。
動態分配由alloca函數完成。
棧的動態分配不需要釋放(自動),也沒有釋放函數。
對於便攜程序,不鼓勵動態分配堆棧。
堆空間分配是動態的,雖然在程序的末尾,所有的數據空間都將被釋放回系統中,但是精確的應用程序內存/空閑內存匹配是良好應用程序的基本要素。
堆內存用於保存由新分配的內存在堆中創建的對象和數組,並由虛擬機的自動垃圾收集器管理。
創建了一個數組或對象在堆中,堆棧可以也是一個特殊的變數,讓棧中這個變數的值等於數組或對象在堆內存地址,棧中的變數是一個數組或對象的引用變數,它可用於程序後引用變數來訪問堆中的堆棧數組或對象,引用變數是一個數組或對象名稱。
引用變數是在定義時在堆棧中分配的普通變數,並且在程序超出其範圍後會釋放引用的變數。
海南電腦培訓發現和數組在堆中分配和對象本身,即使您的應用程序是使用新的數組或對象聲明的一個代碼塊,數組和對象本身佔用內存不會被釋放,數組和對象沒有引用變數指向它,成為一種浪費,不在使用,但仍佔據內存空間,其次是垃圾收集器在一個不確定的時間。
java中堆和棧的區別主要在於
第一,從軟體設計的角度看,棧代表了處理邏輯,而堆代表了數據。這樣分開,使得處理邏輯更為清晰。分而治之的思想。這種隔離、模塊化的思想在軟體設計的方方面面都有體現。
第二,堆與棧的分離,使得堆中的內容可以被多個棧共享(也可以理解為多個線程訪問同一個對象)。這種共享的收益是很多的。一方面這種共享提供了一種有效的數據交互方式(如:共享內存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節省了空間。
第三,棧因為運行時的需要,比如保存系統運行的上下文,需要進行地址段的劃分。由於棧只能向上增長,因此就會限制住棧存儲內容的能力。而堆不同,堆中的對象是可以根據需要動態增長的,因此棧和堆的拆分,使得動態增長成為可能,相應棧中只需記錄堆中的一個地址即可。
第四,面向對象就是堆和棧的完美結合。其實,面向對象方式的程序與以前結構化的程序在執行上沒有任何區別。但是,面向對象的引入,使得對待問題的思考方式發生了改變,而更接近於自然方式的思考。當我們把對象拆開,你會發現,對象的屬性其實就是數據,存放在堆中;而對象的行為(方法),就是運行邏輯,放在棧中。我們在編寫對象的時候,其實即編寫了數據結構,也編寫的處理數據的邏輯。不得不承認,面向對象的設計,確實很美。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/254343.html