PHP变量内存占用分析
来源:互联网 发布:常用数据采集卡型号 编辑:程序博客网 时间:2024/04/30 11:55
前言
都说PHP内存占有率太大,究竟有多大,有个量级吗?一起来看看吧。
1. 环境假设
PHP5.4.3|64位机器
2. 从PHP变量存储结构看存储空间大小
2.1 原生类型(boolean,char,int,short,long,float,double)
PHP中,所有变量存储为zvaltypedef struct _zval_struct zval;struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount__gc; zend_uchar type; /* active type */ zend_uchar is_ref__gc;};
考虑8字节内存对齐,定义8字节向上取整伪函数ceil8()。sizeof(zval)=ceil8(sizeof(zvalue_value+4+1+1))。
再看zvalue_valuetypedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj;} zvalue_value;
sizeof(zvalue_value)=max(sizeof(str),sizeof(zend_object_value))=max(16,sizeof(zend_object_value))。
再看zend_object_valuetypedef unsigned int zend_object_handle;typedef struct _zend_object_handlers zend_object_handlers;typedef struct _zend_object_value { zend_object_handle handle; const zend_object_handlers *handlers;} zend_object_value;
sizeof(zend_object_value)=16
合计一下,原生类型(boolean,char,int,long,float,double)在PHP中的存储大小=sizeof(zval)=24。2.2 空类大小
回到2.1节中关于sizeof(zvalue_value)的讨论。对于空类而言,zvalue_value的内存大小由两部分组成,一部分是sizeof(zvalue_value),另一部分是sizeof(zend_object_handlers)。而zend_object_handlers定义为struct _zend_object_handlers { /* general object functions */ zend_object_add_ref_t add_ref; zend_object_del_ref_t del_ref; zend_object_clone_obj_t clone_obj; /* individual object functions */ zend_object_read_property_t read_property; zend_object_write_property_t write_property; zend_object_read_dimension_t read_dimension; zend_object_write_dimension_t write_dimension; zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; zend_object_get_t get; zend_object_set_t set; zend_object_has_property_t has_property; zend_object_unset_property_t unset_property; zend_object_has_dimension_t has_dimension; zend_object_unset_dimension_t unset_dimension; zend_object_get_properties_t get_properties; zend_object_get_method_t get_method; zend_object_call_method_t call_method; zend_object_get_constructor_t get_constructor; zend_object_get_class_entry_t get_class_entry; zend_object_get_class_name_t get_class_name; zend_object_compare_t compare_objects; zend_object_cast_t cast_object; zend_object_count_elements_t count_elements; zend_object_get_debug_info_t get_debug_info; zend_object_get_closure_t get_closure; zend_object_get_gc_t get_gc;};
所有的zend_**_t都是函数指针,sizeof(zend_object_handlers)=26*8=208。
因此,一个空类占用的内存空间为sizeof(zval)+sizeof(zvalue_value)+sizeof(zend_object_handlers)=248。2.3 数组
PHP中数组以HashTable实现。typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; ulong nNextFreeElement; Bucket *pInternalPointer; /* Used for element traversal */ Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets; dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection;#if ZEND_DEBUG int inconsistent;#endif} HashTable;typedef void (*dtor_func_t)(void *pDest);typedef unsigned char zend_bool;
考虑n维数组。HashTable的内存大小由两部分组成:sizeof(HashTable)以及n*sizeof(Bucket)。
考虑n维数组并忽略ZEND_DEBUG,sizeof(HashTable)=4+4+4+8+8+8+8+8+8+1+1+1=64。
来看下Buckettypedef struct bucket { ulong h; /* Used for numeric indexing */ uint nKeyLength; void *pData; void *pDataPtr; struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; struct bucket *pLast; const char *arKey;} Bucket;
Bucket的内存大小由两部分组成,sizeof(Bucket)以及pData指向的数据,通常是zval或者zval*,因此可以用sizeof(zval)去量化。
sizeof(Bucket)=ceil8(8+4+8*7)=72。
合计一下,对于2.1节的原生数组,一个n维数组的大小为sizeof(HashTable)+n*(sizeof(Bucket)+sizeof(zval))=64+96n。
对于2.2节的空类数组,一个n维数组的大小为sizeof(HashTable)+n*(sizeof(Bucket)+sizeof(zval))=64+320n。
3. 高级语言间横向对比
好了,这回和邻居家的语言JAVA,C++比较下,看看差距。这里假设C++编译环境为64位机器,JAVA的虚拟机环境为64位,hotspot
- PHP变量内存占用分析
- Nginx+PHP内存占用分析
- PHP数组占用很大内存的分析
- php怎么查看一个变量的占用内存
- 内存的变量占用
- PHP查询MySQL大量数据的内存占用分析
- PHP查询MySQL大量数据的内存占用分析
- PHP查询MySQL大量数据的内存占用分析
- PHP查询MySQL大量数据的内存占用分析
- PHP查询MySQL大量数据的内存占用分析 【转】
- 程序占用内存分析
- 内存占用分析
- linux内存占用分析
- 内存占用分析
- linux内存占用分析
- VGGNet 内存占用分析
- 内存_内存占用分析
- php-fpm 内存占用过大
- POI(信息点)数据库
- iOS开发——iOS10升级极光推送SDK、友盟分享SDK
- udf实例
- Java面试题大全(Java基础九)
- Android调取系统相册和相机照片设置到ImageView并上传到服务器
- PHP变量内存占用分析
- web安全之分布式拒绝攻击-ddos与防范方法
- #Paper Reading# Robust Word-Network Topic Model for Short Texts
- CentOS搭建ActiveMQ
- 欢迎使用CSDN-markdown编辑器
- 一排石头的游戏
- IntelliJ Idea 常用快捷键列表
- 大型网站技术架构(三):关于架构体系的补充
- Eclipse工程导入Android studio记录