PHP对象类型在内存中的分配

来源:互联网 发布:设计淘宝店招 评课 编辑:程序博客网 时间:2024/05/01 01:06

  对像类型在PHP 里面和整型、浮点型、字符串型一样,也是一种数据类型,都是存储不同类型数据用的, 在运行的时候都要加载到内存中去用,那么对象在内存里面是怎么体现的呢?内存从逻辑上说大体上分为4 段:栈空间段、堆空间段、代码段、初始化静态段,程序里面不同的声明放在不同的内存段里面,程序中不同类型数据的声明将会被存放在不同的内存段里。每段内存的特点如下。 
  
1.栈空间段(栈内存)
  栈(stack)的特点是空间小但被CPU访问的速度快,是用户存放程序中临时创建的变量。由于栈的后进先出特点,所以栈特别方便用来保存和恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个临时数据寄存、交换的内存区。用于存储占用空间长度不变且占用空间小的数据类型的内存段,例如整型1、100、100000等在内存中占用空间是等长的,占用的空间都是32位4个字节。还有double、boolean等都可以存储在栈空间段中。
  
2.堆空间段(堆内存)
  堆(heap)是用来存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。用于存储数据长度可变或占用内存比较大的数据。例如,字符串、数组和对象就存储在这段内存中。

3.数据段
  数据段(data segment)通常是指用来存放程序中已初始化且不为0的全局变量,如:静态变量和常量。
  
4.代码段
  代码段(code segment / text segment)通常是指用来存放程序执行代码的一块内存区域,比如函数和方法。代码段需要防止在运行时被非法修改,所以只准读取操作,而不允许写入(修改)操作。

这里写图片描述

  对象类型的数据就是一种占用空间比较大的数据类型,并且是占用的空间不定长的数据类型,所以对象创建完成以后被存放在堆内存中,但对象的引用名称是存放在栈里面的。程序在运行时,栈内存中的数据是可以直接存取的,而堆内存是不可以直接存取的内存。但可以通过对象的引用名称来访问对象中的成员,即通过对象名称使用对象。
这里通过Person类实例化的三个对象使用图形,来说明对象类型的数据是如何在内存中存储的。

这里写图片描述

   从上图可以看出$p1=new Person();等号右边是真正的对象实例,在堆内存里面的实体,而等号右边则是对象的引用,存储在栈内存段中。

  在PHP中,只要使用一个new这个关键字,就会实例化出来一个对象,并在堆里面开辟一块自己的空间。上图一共有3次new Person(),所以会在堆里面开辟3 个空间,产生3 个实例对象,每个对象之间都是相互独立的,使用自己的空间。
  在内存中,存储数据的每个空间都有独立的内存地址,内存的地址通常是使用十六进制数表示,对象中的每个成员在堆内存中存储时都会有一个地址。
  每个在堆里面的实例对象是存储属性的,比如说,现在堆里面的实例对象里面都存有姓 名、性别和年龄。每个属性又都有一个地址。 $p1=new Person();等号的右边$p1 是一个引用变量,通过赋值运算符“=”把对象的首地址 赋给“$p1”这个引用变量,所以$p1 是存储对象首地址的变量,$p1 放在栈内存里边,$p1 相当 于一个指针指向堆里面的对象,所以我们可以通过$p1 这个引用变量来操作对象,通常我们也 称对象引用为对象。 如上图,第一个对象的首地址为“0xff001”,如果在程序中知道内存的首地址,就会按顺序找到对象中的每个成员。而在“$person1=new Person();” 语句中,通过赋值运算符“=”把第一个对象在堆内存中的首地址“0xff001”赋给了变量$person1,所以等号左边的$person1就是第一个对象的引用变量。变量$person1存放的是一个十六进制整数,被存放在栈内存中。$person1是一个存储地址的变量,相当于一个指针指向堆里面的对象。所以访问第一个对象中的每个成员都要通过这个引用变量$person1来完成,通常也可以吧对象引用当成对象来看待。同样,第二个对象的首地址“0xff002”赋给栈里面的引用变量“$person2”,通过这个引用变量访问第二个对象中的每个成员。以此类推。

0 0