php内存管理

PHP内存管理实现:当变量赋值传递是不是直接进行深拷贝,而是多个变量共用同一个value,引用计数来记录value有多少个变量再使用,当某个变量发生变化是,这个时候无法继续和之前变量共用value时,这个时候就会进行深拷贝,分离value,这个时候是写的复制。

eg:

$a = array();//$a refcount=1

$b = $a;//$a $b refcount=2

$c = $b;//$a $b $c refcouny=3

unset($b) //$a $c refcount=2

从上面可以看出当数据被赋值时PHP并不会拷贝,而是将refcount的值加一;

引用计数:记录有多少个zval执行zend_value,当有新的zval指向它时refcount就会加1,当refcount为0时,表示value已经没有被指向,这是value就会进行释放。(并不是所有的value结构类型都会用到引用计数,比如整形、浮点型、布尔型、null.他们直接通过zval保存,因此这些类型不会共用value,而是深拷贝,这是PHP7特有的,这样做是对一些占用内存小的数据省去了计数的过程,正对PHP7对数据存储可以参考https://www.jb51.net/article/148865.htm)还有一种特殊的情况不会用到引用计数:

$a = 'aa';

$b = $a;

上面的这段不会用到引用计数,因为$a是一个唯一不变的值,这些字符串的生命周期是整个请求执行期间,request完成后会统一销毁释放,所以就无须在运行期间来引用计数。还有一种就是不可变数组。

$a = 'aa'.time();

$b = $a;//这种会用到引用计数。refcount=2

哪一组数据看:

var_dump(memory_get_usage());//获取内存方法,加上true返回实际内存,不加则返回表现内存
$a = 324324;
var_dump(memory_get_usage());
unset($a);
var_dump(memory_get_usage());
int(349016) int(349016) int(349016)//这里不管$a是不变的(比较小的)字符串、整型、浮点型其都不会受unset影响,因为其值是存在zend_value中的,思路参考:https://www.jb51.net/article/148865.htm
var_dump(memory_get_usage());//获取内存方法,加上true返回实际内存,不加则返回表现内存
$a = time().'hazel';
$b = $a;
$c = time().'hazel2';
var_dump(memory_get_usage());
unset($a);//当我们把这一段去掉会发现值是不变的,因为他是引用计数,删掉a不会减少内存,除非$a和$b都删除。
unset($c);
var_dump(memory_get_usage());
int(349024) int(349112) int(349064)

写时复制:

$a = 10;//将常量值赋给变量,会为a分配内存空间

$b $a;//变量赋值给变量,是不是copy了一份副本,b也分配了内存空间呢?

$c = &$a;//引用是不会为c分配空间的,c和a是共用一份空间的。

$a = 5;

echo $c;//输出5,因为a和c 是指向同一个内存空间

echo PHP_EOL;

echo $b;//由于b是副本,对a的操作不会影响b,输出10

最后 refcount=2  is_ref_gc=1  

回收机制:

回收机制有两种情况:

1、refcount=0;

  • 对每个根缓冲区中的根zval按照深度优先遍历算法遍历所有能遍历到的zval,并将每个zval的refcount减1,同时为了避免对同一zval多次减1(因为可能不同的根能遍历到同一个zval),每次对某个zval减1后就对其标记为“已减”。
  • 再次对每个缓冲区中的根zval深度优先遍历,如果某个zval的refcount不为0,则对其加1,否则保持其为0。
  • 清空根缓冲区中的所有根(注意是把这些zval从缓冲区中清除而不是销毁它们),然后销毁所有refcount为0的zval,并收回其内存。

2、还有一种是针对数组和对象的:如果一个值的refcount减少后还大于0,那么垃圾回收器会把它当成一个垃圾的value收集,等达到一定数量后开启垃圾鉴定程序,把真正的垃圾释放掉。

回收算法:

参考:https://www.cnblogs.com/lovehappying/p/3679356.html

猜你喜欢

转载自blog.csdn.net/qq_38234594/article/details/88369748
今日推荐