摘要:下面的做法會占用多大的內存測試上面運行輸出的結果如下可見數組占用的內存遠大于正常分配的內容原理在中都使用類型來代表數字,沒有使用類型。最大成員數據空間是,指針占用字節,占用字節,共字節。參考數組占用內存大小分析
下面的做法會占用多大的內存?
list($appid,$openid) = ["testcontent","test"];測試
$m0 = memory_get_usage(); $k = range(1,200000); $m1 = memory_get_usage(); echo round(($m1-$m0)/pow(1024,2),4) ."MB "; 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 "; $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 ";
上面運行輸出的結果如下:
27.9404MB 51.3041MB 9.1553MB
可見數組占用的內存遠大于正常分配的內容
原理在PHP中都使用long類型來代表數字,沒有使用int類型。大家都明白PHP是一種弱類型的語言,它不會去區分變量的類型,沒有int float char *之類的概念。我們看看php在zend里面存儲的變量,PHP中每個變量都有對應的 zval,Zval結構體定義在Zend/zend.h里面,其結構:
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結構來存儲變量的值,即zvalue_value 是一個union,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;
最大成員數據空間是struct str,指針占*val用4字節,INT占用4字節,共8字節。
struct zval占用的空間為8+4+1+1 = 14字節,其實呢,在zval中數組,字符串和對象還需要另外的存儲結構,數組則是一個 HashTable:
HashTable結構體定義在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;
HashTable 結構需要 39 個字節,每個數組元素存儲在 Bucket 結構中:
typedef struct bucket { ulong h; /* Used for numeric indexing 4字節 */ uint nKeyLength; /* The length of the key (for string keys) 4字節 */ void *pData; /* 4字節*/ void *pDataPtr; /* 4字節*/ struct bucket *pListNext; /* PHP arrays are ordered. This gives the next element in that order4字節*/ struct bucket *pListLast; /* and this gives the previous element 4字節 */ struct bucket *pNext; /* The next element in this (doubly) linked list 4字節*/ struct bucket *pLast; /* The previous element in this (doubly) linked list 4字節*/ char arKey[1]; /* Must be last element 1字節*/ } Bucket;
Bucket 結構需要 33 個字節,鍵長超過四個字節的部分附加在 Bucket 后面,而元素值很可能是一個 zval 結構,另外每個數組會分配一個由 arBuckets 指向的 Bucket 指針數組, 雖然不能說每增加一個元素就需要一個指針,但是實際情況可能更糟。這么算來一個數組元素就會占用 54 個字節,與上面的估算幾乎一樣。
一個空數組至少會占用 14(zval) + 39(HashTable) + 33(arBuckets) = 86 個字節,作為一個變量應該在符號表中有個位置,也是一個數組元素,因此一個空數組變量需要 118 個字節來描述和存儲。從空間的角度來看,小型數組平均代價較大,當然一個腳本中不會充斥數量很大的小型數組,可以以較小的空間代價來獲取編程上的快捷。但如果將數組當作容器來使用就是另一番景象了,實際應用經常會遇到多維數組,而且元素居多。比如10k個元素的一維數組大概消耗540k內存,而10k x 10 的二維數組理論上只需要 6M 左右的空間,但是按照 memory_get_usage 的結果則兩倍于此,[10k,5,2]的三維數組居然消耗了23M,小型數組果然是劃不來的。
參考php數組占用內存大小分析
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21542.html
摘要:鑒于文件讀寫網絡編程,或者說字節流處理的重要性,掌握這兩個函數是邁向高級編程的基礎。相比之下字節處理門庭冷落,相關函數寥寥無幾。上述是函數簡單的使用場景,接下來分別介紹和函數。如其名,函數的工作是將數據按照格式打包成字節數組。 轉載請注明文章出處:https://tlanyan.me/php-pack-a... PHP有兩個重要的冷門函數:pack和unpack。在網絡編程,讀寫圖像...
摘要:由開源出來的一個性能監控工具,占用資源很少,甚至能夠在生產環境中進行部署。使用說明方法名稱。方法調用次數在同級方法總數調用次數中所占的百分比。單位微秒方法執行花費的時間百分比。單位字節峰值百分比。 xhprof由facebook開源出來的一個PHP性能監控工具,占用資源很少,甚至能夠在生產環境中進行部署。它可以結合graphviz使用,能夠以圖片的形式很直觀的展示代碼執行耗時。下面主要...
摘要:關于結構體內存對齊是什么,請參考源碼學習內存管理筆記。這說明在當前情況下,字符串結構中的柔性數組的起始位置并不受是否加關鍵字而影響,是緊跟在結構體后面的,所以節省內存這個說法并不成立。 baiyan 全部視頻:https://segmentfault.com/a/11... 今天我們正式進入redis5源碼的學習。redis是一個由C語言編寫、基于內存、單進程、可持久化的Key-Va...
摘要:對于不同的實現,對象占用的內存空間大小可能不盡相同,本文主要分析中的情況,實驗環境為位系統,使用進行結論驗證。內存占用這里分析一個只有一組鍵值對的結構如下首先分析本身的大小。 本文深入分析并驗證了不同Java對象占用內存空間大小的情況。對于不同的jvm實現,Java對象占用的內存空間大小可能不盡相同,本文主要分析HotSpot jvm中的情況,實驗環境為64位window10系統、JD...
閱讀 2319·2021-11-23 09:51
閱讀 3752·2021-11-11 10:57
閱讀 1400·2021-10-09 09:43
閱讀 2489·2021-09-29 09:35
閱讀 2019·2019-08-30 15:54
閱讀 1792·2019-08-30 15:44
閱讀 3185·2019-08-30 13:20
閱讀 1694·2019-08-30 11:19