PHP真的這麼耗內存麼?於是藉此機會了解了PHP的資料類型實現方式。本文主要介紹PHP數組記憶體利用率低和弱型別詳細解讀,具有一定的參考價值,有興趣的小夥伴可以參考一下。
先來做個測驗:
##
<?php echo memory_get_usage() , '<br>'; $start = memory_get_usage(); $a = Array(); for ($i=0; $i<1000; $i++) { $a[$i] = $i + $i; } $end = memory_get_usage(); echo memory_get_usage() , '<br>'; echo 'argv:', ($end - $start)/1000 ,'bytes' , '<br>';所得結果: 353352
# 437848
argv: 84.416bytes
<?php $start = memory_get_usage(); $a = array_fill(0, 10000, 1); $end = memory_get_usage(); //10k elements array; echo 'argv:', ($end - $start )/10000,'byte' , '<br>';輸出為:argv:54.5792byte
#
typedef struct _zval_struct zval; struct _zval_struct { /* Variable information */ zvalue_value value; /* The value 1 12字节(32位机是12,64位机需要8+4+4=16) */ zend_uint refcount__gc; /* The number of references to this value (for GC) 4字节 */ zend_uchar type; /* The active type 1字节*/ zend_uchar is_ref__gc; /* Whether this value is a reference (&) 1字节*/ };PHP使用union結構來儲存變數的值,zval中zvalue_value類型的value變數即為一個union,定義如下:
typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { /* string value */ char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; /*object value */ } zvalue_value;union類型佔用記憶體的大小有其最大的成員所佔的資料空間決定。在zvalue_value中,str結構體的int佔4字節,char指標佔4字節,故整個zvalue_value所佔記憶體為8位元組。
typedef struct _hashtable { uint nTableSize; //表长度,并非元素个数 uint nTableMask;//表的掩码,始终等于nTableSize-1 uint nNumOfElements;//存储的元素个数 ulong nNextFreeElement;//指向下一个空的元素位置 Bucket *pInternalPointer;//foreach循环时,用来记录当前遍历到的元素位置 Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets;//存储的元素数组 dtor_func_t pDestructor;//析构函数 zend_bool persistent;//是否持久保存。从这可以发现,PHP数组是可以实现持久保存在内存中的,而无需每次请求都重新加载。 unsigned char nApplyCount; zend_bool bApplyProtection; } HashTable;除了幾個記錄table大小,所含元素數量的屬性變數外,Bucket被多次使用到,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]; /* Must be last element */ } Bucket;有點像是鍊錶,Bucket就像是鍊錶節點,有具體的資料和指針,而HashTable就是一個array ,保存著一串Bucket元素。 PHP中多維數組的實現,不過就是Bucket裡面存著另一個HashTable罷了。
以上是PHP數組記憶體利用率低詳解解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!