PHP對象在內存中的分配

jopen 10年前發布 | 13K 次閱讀 PHP PHP開發

網上看到一篇文章很好,其中:$p1=new Person();對象的首地址賦給“$p1”這個引用變量,所以$p1 是存儲對象首地址的變量,$p1 放在棧內存里邊,$p1 相當 于一個指針指向堆里面的對象,所以我們可以通過$p1 這個引用變量來操作對象,通常我們也 稱對象引用為對象。但是對于php手冊中搶到&并非C語言中的指針地址,讓我有種疑問,于是向前輩及大俠們請教了下,得到了大家確認的支持排除了疑惑。再次記錄下來補充實例以備溫故知新。
      對像在PHP 里面和整型、浮點型一樣,也是一種數據類,都是存儲不同類型數據用的, 在運行的時候都要加載到內存中去用,那么對象在內存里面是怎么體現的呢?
內存從邏 輯上 說大體上是分為4 段,棧空間段、堆空間段、代碼段、初始化靜態段,程序里面不同的聲明 放在不同的內存段里面。
數據段(data segment)通常是指用來存放程序中已初始化且不為0的全局變量如:靜態變量和常量;
代碼段
(code segment / text segment)通常是指用來存放程序執行代碼的一塊內存區域,比如函數和方法;
棧空間段
存儲占用相同空間長度并且占用空間小的數據類型的地方,比如說整型1,10,100,1000,10000,100000 等等,在內存里面占用空間是等長的,都是64 位4 個字節。
堆內存 數據長度不定長,而且占有空間很大的數據類型的數據。如下圖:
PHP對象在內存中的分配
棧內存是可以直接存取的,而堆內存不可以直接存取。$p1=new Person(); $p2=new Person(); $p3=new Person();
對于我們的對象來說就是一種大的數據類型而且是占用空間不定長的類型,所以說對象是放在堆里面的,但對象名稱是放在棧里面的,這樣通過對象名稱就可以使用對象了。
$p1 就是我們實例出來的對象名稱,同理,$p2,$p3 也是我們實例出來的對象名稱,一個類可以實例出多個對象,每個對象都是獨立的,
上面的代碼相當于實例出來3 個人來,每個人之間是沒有聯系的,只能說明他們都是人類,每 個人都有自己的姓名,性別和年齡的屬性,每個人都有說話和走路的方法,只要是類里面體 現出 來的成員屬性和成員方法,實例化出來的對象里面就包含了這些屬性和方法。
$p1=new Person();
對于這個條代碼,$p1 是對象名稱在棧內存里面new Person()是真正的對象是在堆內存 里面的,具體的請看下圖:
PHP對象在內存中的分配
從上圖可以看出$p1=new Person();等號右邊是真正的對象實例,在堆內存里面的實體, 
上圖一共有3 次new Person(),所以會在堆里面開辟3 個空間,產生3 個實例對象,每個對象之間都是相互獨立的,使用自己的空間,
在PHP 里面,只要有一個new 這個關鍵字出現就會 實例化出來一個對象,在堆里面開辟一塊自己的空間。 
每個在堆里面的實例對象是存儲屬性的,比如說,現在堆里面的實例對象里面都存有 姓 名、性別和年齡。每個屬性又都有一個地址。 
$p1=new Person();等號的右邊$p1 是一個引用變量,通過賦值運算符“=”把對象的首地址 賦給“$p1”這個引用變量,所以$p1 是存儲對象首地址的變量,$p1 放在棧內存里邊,$p1 相當 于一個指針指向堆里面的對象,所以我們可以通過$p1 這個引用變量來操作對象,通常我們也 稱對象引用為對象。 
當時看到這里沒有完全相信,為此處特意做了驗證:

class Person{
  public $name;
}

$obj1 = new Person();
$obj1->name = "test1";
echo $obj1->name;
$obj2 = $obj1;
$obj2->name = "test2";
echo $obj1->name;
echo $obj2->name;

通過測試結果來看,解釋是對的。
$p1 是對象的指針而不是對象本身
 obj2和 obj1都指向同一塊內存同一個對象這一點和OOP語言是一樣

object(Person)[2] 
public 'name' => string 'test2' (length=5)

object(Person)[2]
public 'name' => string 'test2' (length=5)
可見對象的ID號是一個

如果想得到一個對象的副本,用$obj2 =clone $obj1;  用了clone后會產生一個新對象,分配內存,獨立于原來的obj1
參見手冊此頁  http://www.php.net/manual/zh/language.oop5.cloning.php

$obj2 = $obj1;
$obj2 = &$obj1;
一樣的效果,一樣的解釋?
對于object來說,是一樣的。 對于普通的變量是不一樣的。
$a = 1;
$b = $a;
$c = &$a;
不一樣的 

 

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!