Memory usage analysis of PHP arrays

Source: Internet
Author: User
How much memory does PHP array occupy?

list($appid,$openid) = ["testcontent","test"];
Test
$m0 = memory_get_usage();$k = range(1,200000);$m1 = memory_get_usage();echo round(($m1-$m0)/pow(1024,2),4) ."MB\n";foreach ($k as $i){    $n1 = "kk$i";    $n2 = "tt$i";    list($$n1,$$n2) = [$i,$i*3];}$m2 = memory_get_usage();echo round(($m2-$m1)/pow(1024,2),4) ."MB\n";$m1 = memory_get_usage();foreach ($k as $i){    $n1 = "kk$i";    $n2 = "tt$i";    $$n1 = $i+time();    $$n2 = 2*time();}$m2 = memory_get_usage();echo round(($m2-$m1)/pow(1024,2),4) ."MB\n";

The output result is as follows:

27.9404MB51.3041MB9.1553MB

It can be seen that the memory occupied by the array is much larger than that normally allocated.

Principle

In PHP, the long type is used to represent numbers, but the int type is not used. Everyone understands that PHP is a weak type language and does not distinguish the type of variables. it does not have the int float char * or other concepts. Let's take a look at the variables stored in php in zend. every variable in PHP has a corresponding zval. the Zval struct is defined in Zend/zend. h, and its structure is as follows:

Typedef struct _ zval_struct zval; struct _ zval_struct {/* Variable information */zvalue_value value; /* The value is 1 12 bytes (32-bit machines are 12, 64-bit machines require 8 + 4 + 4 = 16) */zend_uint refcount _ gc; /* The number of references to this value (for GC) 4 bytes */zend_uchar type;/* The active type 1 byte */zend_uchar is_ref _ gc; /* Whether this value is a reference (&) 1 byte */};

PHP uses a UNION structure to store variable values. that is, zvalue_value is a union, and the memory occupied by the UNION variable is determined by the maximum member data space.

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;  

The maximum member data space is struct str. the pointer occupies 4 bytes for * val, and the INT occupies 4 bytes for 8 bytes. The space occupied by struct zval is 8 + 4 + 1 + 1 = 14 bytes. In fact, in zval, arrays, strings and objects still need to be stored in another structure, the array is a HashTable:

The HashTable struct is defined in Zend/zend_hash.h.

typedef struct _hashtable {      uint nTableSize;//4      uint nTableMask;//4      uint nNumOfElements;//4      ulong nNextFreeElement;//4      Bucket *pInternalPointer;   /* Used for element traversal 4*/      Bucket *pListHead;//4      Bucket *pListTail;//4      Bucket **arBuckets;//4      dtor_func_t pDestructor;//4      zend_bool persistent;//1      unsigned char nApplyCount;//1      zend_bool bApplyProtection;//1  #if ZEND_DEBUG      int inconsistent;//4  #endif  } HashTable; 

The HashTable structure requires 39 bytes, and each array element is stored in the Bucket structure:

Typedef struct bucket {ulong h;/* Used for numeric indexing 4 bytes */uint nKeyLength;/* The length of the key (for string keys) 4 bytes */void * pData; /* 4 bytes */void * pDataPtr;/* 4 bytes */struct bucket * pListNext;/* PHP arrays are ordered. this gives the next element in that order4 byte */struct bucket * pListLast;/* and this gives the previous element 4 byte */struct bucket * pNext; /* The next element in this (doubly) linked list 4 bytes */struct bucket * pLast;/* The previous element in this (doubly) linked list 4 bytes */char arKey [1];/* Must be last element 1 byte */} Bucket;

The Bucket structure requires 33 bytes. the key length of more than four bytes is appended to the Bucket, and the element value is probably a zval structure, in addition, each array is allocated with a Bucket pointer array pointed to by arBuckets. although it cannot be said that a pointer is required for every addition of an element, the actual situation may be worse. In this case, an array element occupies 54 bytes, almost the same as the above estimation.

An empty array occupies at least 14 (zval) + 39 (HashTable) + 33 (arBuckets) = 86 bytes. as a variable, it should have a position in the symbol table, it is also an array element, so an empty array variable requires 118 bytes to describe and store. From the perspective of space, the average cost of small arrays is relatively high. of course, a script won't fill a large number of small arrays, so you can get the programming speed at a small space cost. However, using arrays as containers is another scene. in actual applications, multi-dimensional arrays are often used, and many elements exist. For example, a one-dimensional array with 10 k elements consumes about k of memory, while a 10 k x 10 two-dimensional array requires about 6 M in theory, but the results of memory_get_usage are twice the total space, the 3D array of [10 k, 5, 2] actually consumes 23 MB, and small arrays cannot be included.

Reference

Memory usage analysis of php arrays

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.