You need to enable JavaScript to run this app. PHP7.4 64位环境下简单变量内存占用远超预期问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

PHP7.4 64位环境下简单变量内存占用远超预期问题咨询

测试代码与运行结果

你提供的测试代码如下:

$datetimes = [];
$memory_before = memory_get_usage();

for ($x = 0; $x < 1000; $x++) {
    $datetimes[] = new \DateTime();
}
var_dump('DateTimes: ' . (memory_get_usage() - $memory_before));


$ints = [];
$memory_before = memory_get_usage();

for ($x = 0; $x < 1000; $x++) {
    $ints[] = $x;
}
var_dump('Integers: ' . (memory_get_usage() - $memory_before));

64位PHP 7.4环境运行输出:

string(17) "DateTimes: 350504"
string(15) "Integers: 37160"

内存占用偏高的核心成因

该现象属于PHP底层实现的正常设计,并非异常,主要来自两部分开销:

  1. zval变量封装开销
    PHP是弱类型动态语言,所有变量统一用zval结构体存储,64位PHP 7+版本中单个zval固定占用16字节,除存储实际数值外,还需要携带变量类型标记、引用计数等附加信息,即便是整型也无法直接使用原生8字节存储,本身就比预期占用高一倍。

  2. 数组哈希表的额外开销
    PHP普通数组底层为哈希表(HashTable)实现,为支持随机查找、关联/索引键混用、动态扩容等特性,每个数组元素对应一个Bucket结构体,64位下单个Bucket固定占用32字节,结构如下:

typedef struct _Bucket {
    zval val;       // 16字节,存储变量内容
    zend_ulong h;   // 8字节,存储元素的哈希值
    zend_string *key; // 8字节,存储关联键指针(索引数组时为空)
} Bucket;

同时哈希表为降低哈希冲突概率,槽位数量始终取大于元素数量的最小2次幂,槽位本身是指针数组,每个指针占8字节。
按1000个整型元素计算:

  • 1000个Bucket共占用:1000 * 32 = 32000字节
  • 槽位(大于1000的最小2次幂为1024)共占用:1024 * 8 = 8192字节
  • 加上哈希表基础结构开销,总占用和你测试的37160字节完全吻合。
    百万级元素时的内存占用也和上述计算逻辑成正比,属于正常情况。

低内存存储方案

如果需要存储大量纯索引的同类型数据,可使用SplFixedArray代替普通数组,它是固定长度的顺序存储结构,省去了哈希表的Bucket和空槽位开销,内存占用可降低70%以上。


内容的提问来源于stack exchange,提问作者olidem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 03:18:03