当前位置: 首页 > 编程日记 > 正文

PHP数组实际占用内存大小的分析

http://blog.csdn.net/hguisu/article/details/7376705

我们在前面的php高效写法提到,尽量不要复制变量,特别是数组。一般来说,PHP数组的内存利用率只有 1/10, 也就是说,一个在C语言里面100M 内存的数组,在PHP里面就要1G。下面我们可以粗略的估算PHP数组占用内存的大小,首先我们测试1000个元素的整数占用的内存:

<?php  
echo memory_get_usage() , '<br>';  
$start = memory_get_usage();  
$a = Array();  
for ($i=0; $i<1000; $i++) {  
$a[$i] = $i + $i;  
}  
$mid =  memory_get_usage();  
echo memory_get_usage() , '<br>';  
for ($i=1000; $i<2000; $i++) {  
$a[$i] = $i + $i;  
}  
$end =  memory_get_usage();  
echo memory_get_usage() , '<br>';  
echo 'argv:', ($mid - $start)/1024 ,'kb' , '<br>';  
echo 'argv:',($end - $mid)/1024 ,'kb' , '<br>';  

输出是:

350752
435248
519424
argv:84.416byte
argv:84.176byte

大概了解1000 个元素的整数数组需要占用 82k 内存,平均每个元素占用 84 个字节。而纯 C 中整体只需要 4k(一个整型占用4byte * 1000 )。memory_get_usage() 返回的结果并不是全是被数组占用了,还要包括一些 PHP 运行本身分配的一些结构,可能用内置函数生成的数组更接近真实的空间:

<?php  
$start = memory_get_usage(true);  
$a = array_fill(0, 10000, 1);  
$mid = memory_get_usage(true); //10k elements array;   
echo 'argv:', ($mid - $start )/10000,'byte' , '<br>';  
$b = array_fill(0, 10000, 1);  
$end = memory_get_usage(true); //10k elements array;   
echo 'argv:', ($end - $mid)/10000 ,'byte' , '<br>';  

得到:
argv:54.5792byte
argv:54.5792byte

从这个结果来看似乎一个数组元素大约占用了54个左右的字节。再看看数组在Zend里面的C结构,PHP中的数组变量,首先需要一个 zval 结构:
struct _zval_struct {
   zvalue_value value;
   zend_uint refcount__gc;
   zend_uchar type;
   zend_uchar is_ref__gc;
};
zvalue_value 是一个union:
typedef union _zvalue_value {
   long lval;
   double dval;
   struct {
       char *val;
       int len;
   } str;
   HashTable *ht;
   zend_object_value obj;
} zvalue_value;

通常 zval 结构需要 8+6=14 个字节,PHP中每个变量都有对应的 zval,但是数组,字符串和对象还需要另外的存储结构,而数组则是一个 HashTable :
typedef struct _hashtable {
    uint nTableSize;
    uint nTableMask;
    uint nNumOfElements;
    ulong nNextFreeElement;
    Bucket *pInternalPointer;
    Bucket *pListHead;
    Bucket *pListTail;
    Bucket **arBuckets;
    dtor_func_t pDestructor;
    zend_bool persistent;
    unsigned char nApplyCount;
    zend_bool bApplyProtection;
} HashTable;
HashTable 结构需要 40 个字节,每个数组元素存储在 Bucket 结构中:
typedef struct bucket {
    ulong h;
    uint nKeyLength;
    void *pData;
    void *pDataPtr;
    struct bucket *pListNext;
    struct bucket *pListLast;
    struct bucket *pNext;
    struct bucket *pLast;
    char arKey[1];
} Bucket;
Bucket 结构需要 36 个字节,键长超过四个字节的部分附加在 Bucket 后面,而元素值很可能是一个 zval 结构,另外每个数组会分配一个由 arBuckets 指向的 Bucket 指针数组, 虽然不能说每增加一个元素就需要一个指针,但是实际情况可能更糟。这么算来一个数组元素就会占用 54 个字节,与上面的估算几乎一样。
    一个空数组至少会占用 14(zval) + 40(HashTable) + 32(arBuckets) = 86 个字节,作为一个变量应该在符号表中有个位置,也是一个数组元素,因此一个空数组变量需要 118 个字节来描述和存储。从空间的角度来看,小型数组平均代价较大,当然一个脚本中不会充斥数量很大的小型数组,可以以较小的空间代价来获取编程上的快捷。但如果将数组当作容器来使用就是另一番景象了,实际应用经常会遇到多维数组,而且元素居多。比如10k个元素的一维数组大概消耗540k内存,而10k x 10 的二维数组理论上只需要 6M 左右的空间,但是按照 memory_get_usage 的结果则两倍于此,[10k,5,2]的三维数组居然消耗了23M,小型数组果然是划不来的。

相关文章:

肝货,详解 tkinter 图形化界面制作流程!

作者 | 黄伟呢来源 | 数据分析与统计学之美本期案例是带着大家制作一个属于自己的GUI图形化界面—>用于设计签名的哦(效果如下图)&#xff0c;是不是感觉很好玩&#xff0c;是不是很想学习呢&#xff1f;限于篇幅&#xff0c;今天我们首先详细讲述一下Tkinter的使用方法。tk…

迁移碰到数据库 Unknown collation: 'utf8mb4_unicode_ci'

数据库从香港服务器迁移到阿里云的虚拟主机&#xff0c;不得不吐槽一下。阿里云的ftp好慢&#xff0c;db导入面板也不够友好。 还得靠中断命令行链接&#xff0c;结果版本太低不支持 utf8mb4_unicode_ci&#xff0c;尼玛&#xff0c;现在都mysql5.7了&#xff0c;您还在 5.1时代…

15-shell 输入/输出重定向

大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入&#xff0c;默认情况下&#xff0c;这恰好是你的终端。同样&#xff0c;一个命令通常将其输出写入到标准输出&#xff0c;默认情况下&#xff0c;这也是…

高性能Mysql主从架构的复制原理及配置详解

1 复制概述Mysql内建的复制功能是构建大型&#xff0c;高性能应用程序的基础。将Mysql的数据分布到多个系统上去&#xff0c;这种分布的机制&#xff0c;是通过将Mysql的某一台主机的数据复制到其它主机&#xff08;slaves&#xff09;上&#xff0c;并重新执行一遍来实现的。复…

gdal 1.9+python 2.7开发环境配置

最近项目使用Cesium平台基于WegGl做web地球&#xff0c;其中关于地形数据有一种支持格式为terrain的地形数据。这种格式可以通过一个python工具切dem来得到。 下面记录下配置gdalpython开发环境&#xff0c;系统是win7 64位&#xff0c;不过gdal和python是32位的&#xff0c;没…

破纪录了!用 Python 实现自动扫雷!

用PythonOpenCV实现了自动扫雷&#xff0c;突破世界记录&#xff0c;我们先来看一下效果吧。中级 - 0.74秒 3BV/S60.81相信许多人很早就知道有扫雷这么一款经典的游&#xff08;显卡测试&#xff09;戏&#xff08;软件&#xff09;&#xff0c;更是有不少人曾听说过中国雷圣&a…

java高并发编程(二)

马士兵java并发编程的代码&#xff0c;照抄过来&#xff0c;做个记录。 一、分析下面面试题 /*** 曾经的面试题&#xff1a;&#xff08;淘宝&#xff1f;&#xff09;* 实现一个容器&#xff0c;提供两个方法&#xff0c;add&#xff0c;size* 写两个线程&#xff0c;线程1添加…

LAMP 关键数据集锦技术选项参考

LAMP 关键数据集锦技术选项参考 源自日积月累自己的其他人的经验总结负载均衡 LVS工作在四层&#xff0c;内核态&#xff0c;性能极高&#xff0c;有VIP功能&#xff0c;配合 keepalived 做有效的 心跳检查和负载均衡安装配置麻烦&#xff0c;HAProxy工作在四层到七层&am…

centos7 设置中文

查看系统版本[rootwebtest76 ~]# cat /etc/redhat-releaseCentOS Linux release 7.0.1406 (Core) [rootlocalhost ~]# cat /etc/locale.conf LANGen_US.UTF-8[rootlocalhost ~]# cp /etc/locale.conf /etc/locale.conf_bak[rootlocalhost ~]# vim /etc/locale.conf # 修改后原英…

Python最常用的函数、基础语句有哪些?

作者 | 朱卫军来源 | Python大数据分析Python有很多好用的函数和模块&#xff0c;这里给大家整理下我常用的一些方法及语句。一、内置函数内置函数是python自带的函数方法&#xff0c;拿来就可以用&#xff0c;比方说zip、filter、isinstance等。下面是Python官档给出的内置函数…

1.5s~0.02s,期间我们可以做些什么?

原文是在我自己博客中&#xff0c;小伙伴也可以点阅读原文进行跳转查看&#xff0c;还有好听的背景音乐噢背景音乐已取消~ 2333333大爷我就算功能重做&#xff0c;模块重构&#xff0c;我也不做优化&#xff01;&#xff01;&#xff01;运行真快&#xff01; 前言 本文主要探讨…

Python 自动化办公之 Excel 拆分并自动发邮件

作者 | 周萝卜来源 | 萝卜大杂烩今天我们来分享一个真实的自动化办公案例&#xff0c;希望各位 Python 爱好者能够从中得到些许启发&#xff0c;在自己的工作生活中更多的应用 Python&#xff0c;使得工作事半功倍&#xff01;需求需要向大约 500 名用户发送带有 Excel 附件的电…

In Gradle projects, always use http://schemas.andr

2019独角兽企业重金招聘Python工程师标准>>> 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 在做项目自定义时候遇到这个错误 In Gradle projects, always use http://schemas.android.com/apk/res-auto for custom attributes 解决办…

HTTP POST慢速DOS攻击初探

1. 关于HTTP POST慢速DOS攻击 HTTP Post慢速DOS攻击第一次在技术社区被正式披露是今年的OWASP大会上&#xff0c;由Wong Onn Chee 和 Tom Brennan共同演示了使用这一技术攻击的威力。他们的slides在这里&#xff1a; http://www.darkreading.com/galleries/security/applicatio…

Java 学习(20)--异常 /  IO 流

异常&#xff08;Exception&#xff09; (1)程序出现的不正常的情况。 (2)异常的体系 Throwable&#xff08;接口&#xff0c;将异常类对象交给 JVM 来处理&#xff09; |--Error 严重问题&#xff0c;我们不处理。(jvm 错误&#xff0c;程序无法处理) |--Exception 异常 …

runtime自动归档/解档

原文出自&#xff1a;标哥的技术博客 前言 善用runtime&#xff0c;可以解决自动归档解档。想想以前归档是手动写的&#xff0c;确实太麻烦了。现在有了runtime&#xff0c;我们可以做到自动化了。本篇文章旨在学习如何通过runtime实现自动归档和解档&#xff0c;因此不会对所有…

Ivanti 洞察职场新趋势:71% 的员工宁愿放弃升职也要选择随处工作

近日&#xff0c;为从云端到边缘的 IT 资产提供检测、管理、保护和服务的自动化平台供应商 Ivanti 公布了其年度无处不在的办公空间&#xff08; Everywhere Workplace&#xff09; 调查结果。这项调查是Ivanti与全球“未来工作”专家共同完成的&#xff0c;调查范围涵盖 6100 …

Shippable和Packet合作提供原生ARM CI/CD

DevOps自动化平台Shippable和裸金属云服务提供商Packet联合发布了一种新的持续集成和交付&#xff08;CI/CD&#xff09;托管服务&#xff0c;适用于在Armv8-A架构上开发软件应用的开发人员。该解决方案支持开源和商业软件项目&#xff0c;用于在Packet提供的基于ARM的云服务上…

阿里云ECS架设***过程总结

原文地址:最近开发移动项目,数据库服务是架设在电信服务器上,可怜我的联通网络本地调试直接x碎了一地!!度娘相关资料后,最终决定在阿里云ECS上架设作为跳板来访问电信服务器!一.原理1.阿里云ECS上架设.2.本地连接使用拨号到阿里云ECS.3.使用阿里云ECS网络访问电信服务器.使用前…

MYSQL的MERGE存储引擎

MYSQL的引擎不是一般的多&#xff0c;这次说到的是MERGE&#xff0c;这个引擎有很多特殊的地方&#xff1a; MERGE引擎类型允许你把许多结构相同的表合并为一个表。然后&#xff0c;你可以执行查询&#xff0c;从多个表返回的结果就像从一个表返回的结果一样。每一个合并的表必…

Pandas SQL 语法归纳总结,真的太全了

作者 | 俊欣来源 | 关于数据分析与可视化对于数据分析师而言&#xff0c;Pandas与SQL可能是大家用的比较多的两个工具&#xff0c;两者都可以对数据集进行深度的分析&#xff0c;挖掘出有价值的信息&#xff0c;但是二者的语法有着诸多的不同&#xff0c;今天小编就来总结归纳一…

分布式RPC实践--Dubbo基础篇

2019独角兽企业重金招聘Python工程师标准>>> 简介 Dubbo是阿里巴巴开源的一个高性能的分布式RPC框架&#xff0c;整个框架的核心原理来源于生产者与消费者的运作模型&#xff1b;框架的核心分4大部分&#xff1a; 1. 服务注册中心 注册中心主要用于保存生产者消费者…

又居家办公了,要签合同怎么办?

本篇文章暨 CSDN《中国 101 计划》系列数字化转型场景之一。 《中国 101 计划——探索企业数字化发展新生态》为 CSDN 联合《新程序员》、GitCode.net 开源代码仓共同策划推出的系列活动&#xff0c;寻访一百零一个数字化转型场景&#xff0c;聚合呈现并开通评选通道&#xff0…

lombox的用法(省去了set/get/NoArgsConstructor/AllArgsConstructor)

1、环境的搭建&#xff0c;在eclipse下的eclipse.ini中添加以下参数&#xff0c;-Xbootclasspath/a:C:\repository\org\projectlombok\lombok\1.16.6\lombok-1.16.6.jar-javaagent:C:\repository\org\projectlombok\lombok\1.16.6\lombok-1.16.6.jar重启你的eclipse.2、将lombo…

mysql 压力测试脚本

#创建表DEPTCREATE TABLE dept( /*部门表*/deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,dname VARCHAR(20) NOT NULL DEFAULT "",loc VARCHAR(13) NOT NULL DEFAULT "") ENGINEMyISAM DEFAULT CHARSETutf8 ;#创建表EMP雇员CREATE TABLE emp(empno…

C++语言学习(十二)——C++语言常见函数调用约定

C语言学习&#xff08;十二&#xff09;——C语言常见函数调用约定 一、C语言函数调用约定简介 C /C开发中&#xff0c;程序编译没有问题&#xff0c;但链接的时候报告函数不存在&#xff0c;或程序编译和链接都没有错误&#xff0c;但只要调用库中的函数就会出现堆栈异常等现象…

PHP代码保护——Zend Guard

Zend Guard的作用&#xff0c;就是用编译处理的方式来保护PHP源代码免于被反编译查看、未经授权的定制修改、未经许可的使用和重新发布等。而且&#xff0c;它是PHP的东家Zend公司开发的&#xff0c;是完全为PHP量身定做的保护神。 下面&#xff0c;请大家就和我一起来学习使用…

Python 2.4 递归函数

递归函数在函数内部&#xff0c;可以调用其他函数。如果一个函数在内部调用本身&#xff0c;这个函数就是递归函数。举个例子&#xff1a;计算阶乘n!1*2*3*4*5*...*n&#xff0c;用函数fact(n)表示&#xff0c;可以看出fact(n)n!f(n-1)*n所以&#xff0c;fact(n)可以表示为n*fa…

生于俄罗斯的 Web 服务器王者 Nginx,现宣布俄罗斯禁止贡献!

作者 | 苏宓出品 | CSDN不久之前&#xff0c;一些底层工具、软件、开源项目相继宣布在俄罗斯停服&#xff0c;彼时也有不少开发者呼吁 Nginx 是时候进行反限制了。万万没想到&#xff0c;就在国际局势发生改变的一个月后&#xff0c;Nginx 动了手&#xff0c;但是有些「意料之外…

OCP换考题了,052新考题及答案整理-第17题

17、Which two statements are true about tablespaces? A) A database can contain multiple undo tablespaces. B) A database can contain only a single temporary tablespace. C) A database instance stores undo data In the SYSTEM tablespace If no undo tablespace …