php扩展内存管理与引用计数

php 引用 变量 c语言 编程技术
发布日期 2023-06-06 更新日期 2023-06-06 阅读次数 139 文章字数 1.4k

在PHP内核中,大多数情况下都不应该直接使用C语言中自带着malloc、free、strdup、realloc、calloc等操作内存的函数,而应使用内核提供的操作内存的函数,这样可以由内核整体统一的来管理内存。

对于C语言来说,使用malloc()、calloc()、realloc()等动态分配的内存,如果没有指针指向他,就无法进行任何操作,这段内存会一直被程序占用,知道程序运行结束由操作系统回收。

就php代码本身来说,变量是请求感知的,当一个请求结束时,它能够执行与OS在一个进程终止时相同的行为。也就是说,它会隐式地释放所有的为该请求所占用的内存。

C语言原生函数 PHP内核封装后的函数
void malloc(size_t count); void emalloc(size_t count);void pemalloc(size_t count, char persistent);
void calloc(size_t count); void ecalloc(size_t count);void pecalloc(size_t count, char persistent);
void realloc(void ptr, size_t count); void erealloc(void ptr, size_t count);void perealloc(void ptr, size_t count, char persistent);
void strdup(void ptr); void estrdup(void ptr);void pestrdup(void ptr, char persistent);
void free(void ptr); void efree(void ptr);void pefree(void *ptr, char persistent);

对于zval类型的数据,使用的是”引用计数“的技术,至少会有4个成员

1.变量类型 2. 变量值 3. is_ref 代表是否有地址引用 4. refcount 指向该值的变量数量

初始化时,is_ref 为false表示未引用,refcount为1

当一个变量被引用,则zval容器中refcount会减1变为1,变量c指向a,所以refcount会加1变为2,is_ref变为true

垃圾处理时,

如果发现一个zval容器中的refcount在增加,说明不是垃圾

如果发现一个zval容器中的refcount在减少,如果减到了0,直接当做垃圾回收

如果发现一个zval容器中的refcount在减少,并没有减到0,PHP会把该值放到缓冲区,当做有可能是垃圾的怀疑对象

当缓冲区达到临界值,PHP会自动调用一个方法取遍历每一个值,如果发现是垃圾就清理

但是在php扩展中,引用次数需要手动计数,而不会自动计数,这就意味着需要手工管理内存

一般会使用 zval_ptr_dtor(zval *) 减少引用次数

增加则使用 Z_ADDREF_P(zval *) 增加引用次数

一般有几种情况,需要增加引用次数

(1)变量赋值: 变量赋值是最常见的情况,一个用到引用计数的变量类型在初始赋值时其refcount=1,如果后面把此变量又赋值给了其他变量那么就会相应的增加其引用计数
(2)数组操作: 如果把一个变量插入数组中那么就需要增加这个变量的引用计数,如果要删除一个数组元素则要相应的减少其引用
(3)函数调用: 传参实际可以当做普通的变量赋值,将调用空间的变量赋值给被调函数空间的变量,函数返回时会销毁函数空间的变量,这时又会减掉传参的引用,这两个过程由内核完成,不需要扩展自己处理
(4)成员属性: 当把一个变量赋值给对象的成员属性时需要增加引用计数

 


文章作者: 朱丰华

文章链接: https://smart.52dixiaowo.com/blog/post-428.html

版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。

php 引用 变量 c语言

发表评论

相关推荐
朱丰华   |   9个月前   |   php

php判断是否被iframe

246    评论    点赞
朱丰华   |   1年前   |   linux · upx

Linux下安装UPX

450    评论    点赞
朱丰华   |   1年前   |   php

php正则表达式定界符:异常Delimiter must not be alphanumeric or backslash

201    评论    点赞
朱丰华   |   1年前   |   git · hub · 仓库

go克隆并引用github仓库

162    评论    点赞
朱丰华   |   1年前   |   php · 缓存 · opcache

php 加速、提高并发opcache

223    评论    点赞
朱丰华   |   1年前   |   正则 · 表达

正则表达式,实现if...then...else

127    评论    点赞
朱丰华   |   1年前   |   mysql · 变量 · sql

MySQL实现行号-自定义变量

122    评论    点赞
朱丰华   |   1年前   |   变量 · mysql · sql · 用户

MySQL用户自定义变量

111    评论    点赞
朱丰华   |   1年前   |   sql · php

PHP如何使用PDO批量执行SQL?

130    评论    点赞
朱丰华   |   1年前   |   php · 字符 · 字符串

如何在 PHP 中将字符串的第一个字母转换为大写

165    评论    点赞
朱丰华   |   1年前   |   php · 字符 · 正则

php正则表达式原生字符

95    评论    点赞
朱丰华   |   1年前   |   字符 · php · 比较

PHP比较字符串大小相关函数

119    评论    点赞
朱丰华   |   1年前   |   linux · 文件

linux递归统计文件夹大小、du命令_Linux du命令:查看文件夹和文件的磁盘占用情况

207    评论    点赞
朱丰华   |   1年前   |   php

windows下编写、编译php扩展

177    评论    点赞
朱丰华   |   1年前   |   linux · php

linux下编写、编译php扩展

161    评论    点赞
朱丰华   |   1年前   |   js · export · import

js es6 export,import,export default的用法和区别

137    评论    点赞
朱丰华   |   1年前   |   js · vue · 监听

js vue监听,深度监听

122    评论    点赞
朱丰华   |   1年前   |   php · 混淆 · obfuscate · git

yakpro-po混淆php代码

115    评论    点赞
朱丰华   |   1年前   |   c语言 · 编译

C语言中预编译#if的使用

86    评论    点赞
朱丰华   |   1年前   |   php

php扩展编译nts的方法

96    评论    点赞
{{item.author_name}}   |   {{new Date(item.date*1000).log()}}   |   {{it}} ·

{{item.title}}

{{item.uv}}    评论    点赞