
PHP内存管理与垃圾回收机制PHP的内存管理对开发者几乎是透明的但了解底层机制有助于写出更高效的代码。今天说说PHP的内存管理和垃圾回收。PHP使用引用计数来管理内存。每个变量底层是一个zval结构体里面有个refcount字段记录有多少个变量指向它。php$a Hello World;// refcount 1$b $a;// refcount 2$c $b;// refcount 3unset($b);// refcount 2unset($c);// refcount 1unset($a);// refcount 0内存释放?写时复制是PHP的一个重要优化。多个变量指向同一份数据时共享内存只有某个变量要修改时才真正复制。phpfunction copyOnWrite(): void{$data range(1, 100000);$before memory_get_usage(true);$copy $data; // 不复制共享$after memory_get_usage(true);echo 共享时内存: . ($after - $before) . 字节\n;$copy[] 999; // 这里才触发复制$after2 memory_get_usage(true);echo 复制后增加: . ($after2 - $after) . 字节\n;}copyOnWrite();?循环引用是引用计数无法处理的情况。两个对象互相引用它们的refcount永远不会降到0。phpclass Node{public ?Node $next null;public string $name;public function __construct(string $name){$this-name $name;}public function __destruct(){echo Node {$this-name} 被销毁\n;}}function createCycle(): void{$a new Node(A);$b new Node(B);$a-next $b;$b-next $a;echo 循环引用创建\n;unset($a, $b);echo 函数结束\n;}gc_enable();createCycle();$collected gc_collect_cycles();echo 回收了 {$collected} 个循环引用\n;?PHP从5.3开始引入了周期回收算法专门处理循环引用的垃圾。PHP8做了优化引入了更快的回收路径。PHP的内存分配也有自己的策略。Zend Engine维护了内存池小块内存从池里分配减少系统调用。每个请求结束后PHP会释放该请求的所有内存所以即使有内存泄漏也只是在单个请求内有效。内存暂用和释放的几个原则。减少不必要的变量复制循环中及时unset大变量避免循环引用。在Swoole等常驻内存环境中循环引用的内存泄漏会更严重需要更注意。