詳解PHP中的堆和棧
在PHP中共有8種資料型別,其中4中標量型別(字串、布林型、整型、浮點型)、2種複合型別(物件、陣列)、2種特殊型別(資源、NULL)。他們在執行的時候都要載入到記憶體中去用,那麼在記憶體裡面它們是怎麼表示的呢?
初始化靜態常量段:通常是指用來存放程式中已初始化且不為0的全域性變數如:靜態變數和常量。
程式碼段:通常是指用來存放程式執行程式碼的一塊記憶體區域,比如函式和方法。
棧空間段:是儲存佔用相同空間長度並且佔用空間小的資料型別的地方,比如說整型1,10,100,1000,10000,100000 等等,在記憶體裡面佔用空間是等長的,都是64 位4 個位元組。儲存的都是區域性變數,凡是定義在方法中的都是區域性變數(方法外的是全域性變數),變數有自己的作用域,一旦離開作用域,變數就會被釋放。棧記憶體的更新速度很快,因為區域性變數的生命週期都很短。所以在棧空間的資料都是可以通過程式碼手動進行釋放。
棧記憶體段:資料長度不定長,而且佔有空間很大的資料型別的資料。在堆記憶體是裡是不可以直接存取的記憶體,堆記憶體儲存的是陣列和物件(其實陣列就是物件)。凡是new建立的都是在堆中,堆中存放的都是實體(物件),實體用於封裝資料,而且是封裝多個(實體的多個屬性),如果一個數據消失,這個實體也沒有消失,還可以用,所以堆是不會隨時釋放的,但是棧不一樣,棧裡存放的都是單個變數,變數被釋放了,那就沒有了。堆裡的實體雖然不會被釋放,但是會被當成垃圾,最後通過垃圾回收機制去實現垃圾回收。對於我們的物件來數就是一種大的資料型別而且是佔用空間不定長的型別,所以說物件是放在堆裡面的,但物件名稱是放在棧裡面的,這樣通過物件名稱就可以使用物件。
$p1=newPerson();
對於這個條程式碼,$p1 是物件名稱在棧記憶體裡面new Person()是真正的物件是在堆記憶體 裡面的,具體的請看下圖:
從上圖可以看出$p1=new Person();等號右邊是真正的物件例項,在堆記憶體裡面的實體, 上圖一共有3 次new Person(),所以會在堆裡面開闢3 個空間,產生3 個例項物件,每個物件之間都是相互獨立的,使用自己的空間,在PHP 裡面,只要有一個new 這個關鍵字出現就會 例項化出來一個物件,在堆裡面開闢一塊自己的空間。 每個在堆裡面的例項物件是儲存屬性的,比如說,現在堆裡面的例項物件裡面都存有姓 名、性別和年齡。每個屬性又都有一個地址。 $p1=new Person();等號的右邊$p1 是一個引用變數,通過賦值運算子“=”把物件的首地址 賦給“$p1”這個引用變數,所以$p1 是儲存物件首地址的變數,$p1 放在棧記憶體裡邊,$p1 相當 於一個指標指向堆裡面的物件,所以我們可以通過$p1 這個引用變數來操作物件,通常我們也 稱物件引用為物件。
總結:
1、靜態區:存放靜態變數和常量
2、程式碼段:存放函式等程式碼
3、棧空間段:存放區域性變數(自動分配釋放)
4、棧記憶體段:存放物件名(地址)
5、堆:存放物件實體(new後分配,手動釋放或垃圾回收)