lets say I just do this
$arr = array(); for ($i = 0; $i < 10; $i++) $arr[] = $i;
So I store 10 integers in an array. If the integer is a 32b one, the memory cost should be 40 bytes. Problem is, I didn’t tell php that it is an integer so it either has to store it as something else? (js likes to make doubles for example) or keep extra data to remind itself what it is? How much memory do those 10 numbers + the array actually take up in system memory?
Its important since I’m trying to assess the viability of an algorithm I’d like to port to php and its kinda heavy on the memory.
Advertisement
Answer
Your question cannot be easily answered because the exact memory footprint depends on a couple of factors, some of which I’ll try to outline below.
If you just need some quick numbers, consider:
memory_get_usage
— Returns the amount of memory allocated to PHPmemory_get_peak_usage
— Returns the peak of memory allocated by PHP
PHP stores values internally in a structure called the zval:
121 struct _zval_struct { 122 zend_value value; /* value */ 123 union { 124 struct { 125 ZEND_ENDIAN_LOHI_4( 126 zend_uchar type, /* active type */ 127 zend_uchar type_flags, 128 zend_uchar const_flags, 129 zend_uchar reserved) /* call info for EX(This) */ 130 } v; 131 uint32_t type_info; 132 } u1; 133 union { 134 uint32_t var_flags; 135 uint32_t next; /* hash collision chain */ 136 uint32_t cache_slot; /* literal cache slot */ 137 uint32_t lineno; /* line number (for ast nodes) */ 138 uint32_t num_args; /* arguments number for EX(This) */ 139 uint32_t fe_pos; /* foreach position */ 140 uint32_t fe_iter_idx; /* foreach iterator index */ 141 } u2; 142};
This is a union type, meaning it can store values of multiple types. So yes, it keeps extra data to remind itself what it is. Integers are usually represented as longs (32 or 64 bit depending on your platform).
As for arrays, there is an excellent blog post by NikiC giving a detailed explanation. The gist:
| 64 bit | 32 bit --------------------------------------------------- zval | 24 bytes | 16 bytes + cyclic GC info | 8 bytes | 4 bytes + allocation header | 16 bytes | 8 bytes =================================================== zval (value) total | 48 bytes | 28 bytes =================================================== bucket | 72 bytes | 36 bytes + allocation header | 16 bytes | 8 bytes + pointer | 8 bytes | 4 bytes =================================================== bucket (array element) total | 96 bytes | 48 bytes =================================================== total total | 144 bytes | 76 bytes
The above numbers will vary depending on your operating system, your compiler and your compile options. E.g. if you compile PHP with debug or with thread-safety, you will get different numbers. But I think that the sizes given above are what you will see on an average 64-bit production build of PHP 5.3 on Linux.
It’s also worth noting that non-numeric array key labels are an allocation as well, so the longer the labels, the more memory they consume obviously.
The numbers above also depend on which version of PHP you are using. The memory footprint of PHP >= 7 should be much lower than for any PHP < 7 due to internal changes to the Zend Engine. See these two blog posts for details:
- https://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html
- https://nikic.github.io/2015/06/19/Internal-value-representation-in-PHP-7-part-2.html
Also see these resources for more info: