आप किसी चर के सटीक चरण-चिह्न की गणना नहीं कर सकते क्योंकि दो चर स्मृति में एक ही आवंटित स्थान साझा कर सकते हैं
चलो दो सरणियों के बीच स्मृति साझा करने का प्रयास करते हैं, हम देखते हैं कि दूसरे सरणी को आवंटित करने में पहले वाले की स्मृति का आधा हिस्सा खर्च होता है। जब हम पहले वाले को परेशान करते हैं, तो लगभग सभी मेमोरी का उपयोग दूसरे द्वारा किया जाता है।
echo memory_get_usage()."\n"; // <-- 433200
$c=range(1,100);
echo memory_get_usage()."\n"; // <-- 444348 (+11148)
$d=array_slice($c, 1);
echo memory_get_usage()."\n"; // <-- 451040 (+6692)
unset($c);
echo memory_get_usage()."\n"; // <-- 444232 (-6808)
unset($d);
echo memory_get_usage()."\n"; // <-- 433200 (-11032)
इसलिए हम दूसरे एरे की तुलना में आधी मेमोरी का उपयोग नहीं कर सकते, क्योंकि जब हम पहले वाले को परेशान करते हैं तो यह गलत हो जाता है।
पीएचपी में मेमोरी कैसे आवंटित की जाती है और किस उपयोग के लिए उपयोग किया जाता है, इस बारे में पूरी जानकारी के लिए, मैं आपको निम्नलिखित लेख पढ़ने का सुझाव देता हूं: वास्तव में पीएचपी सरणियाँ (और मूल्य) कितनी बड़ी हैं? (संकेत: बड़ा!)
संदर्भ गिनती मूल बातें पीएचपी दस्तावेज में भी स्मृति उपयोग के बारे में जानकारी का एक बहुत कुछ है, और संदर्भ साझा डेटा खंड के लिए गिनती।
यहाँ उजागर विभिन्न समाधान सन्निकटन के लिए अच्छे हैं लेकिन कोई भी PHP मेमोरी के सूक्ष्म प्रबंधन को नहीं संभाल सकता है।
- नव आवंटित स्थान की गणना
यदि आप असाइनमेंट के बाद नया आवंटित स्थान चाहते हैं, तो आपको memory_get_usage()
आवंटन से पहले और बाद में उपयोग करना होगा, क्योंकि कॉपी के साथ इसका उपयोग करने से आपको वास्तविकता का एक गलत दृष्टिकोण मिलता है।
// open output buffer
echo "Result: ";
// call every function once
range(1,1); memory_get_usage();
echo memory_get_usage()."\n";
$c=range(1,100);
echo memory_get_usage()."\n";
याद रखें कि यदि आप पहले के परिणाम को स्टोर करना चाहते हैं memory_get_usage()
, तो चर को पहले से ही पहले से मौजूद memory_get_usage()
होना चाहिए, और एक और पिछली बार बुलाया जाना चाहिए, और हर दूसरे फ़ंक्शन को भी।
यदि आप उपरोक्त उदाहरण में प्रतिध्वनित करना चाहते हैं, तो आउटपुट बफर को खोलने के लिए आवश्यक लेखांकन मेमोरी से बचने के लिए अपने आउटपुट बफर को पहले से ही खोलना होगा।
- आवश्यक स्थान की गणना
यदि आप किसी चर की प्रतिलिपि को संग्रहीत करने के लिए आवश्यक स्थान की गणना करने के लिए फ़ंक्शन पर भरोसा करना चाहते हैं, तो निम्न कोड विभिन्न अनुकूलन का ध्यान रखता है:
<?php
function getMemorySize($value) {
// existing variable with integer value so that the next line
// does not add memory consumption when initiating $start variable
$start=1;
$start=memory_get_usage();
// json functions return less bytes consumptions than serialize
$tmp=json_decode(json_encode($value));
return memory_get_usage() - $start;
}
// open the output buffer, and calls the function one first time
echo ".\n";
getMemorySize(NULL);
// test inside a function in order to not care about memory used
// by the addition of the variable name to the $_GLOBAL array
function test() {
// call the function name once
range(1,1);
// we will compare the two values (see comment above about initialization of $start)
$start=1;
$start=memory_get_usage();
$c=range(1,100);
echo memory_get_usage()-$start."\n";
echo getMemorySize($c)."\n";
}
test();
// same result, this works fine.
// 11044
// 11044
ध्यान दें कि चर नाम का आकार आवंटित मेमोरी में मायने रखता है।
- अपना कोड जांचें !!
एक चर का एक मूल आकार है जिसे PHP स्रोत कोड में उपयोग किए गए आंतरिक सी संरचना द्वारा परिभाषित किया गया है। यह आकार संख्याओं के मामले में उतार-चढ़ाव नहीं करता है। स्ट्रिंग्स के लिए, यह स्ट्रिंग की लंबाई को जोड़ देगा।
typedef 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;
यदि हम चर नाम की गणना को ध्यान में नहीं रखते हैं, तो हम पहले से ही जानते हैं कि चर कितना उपयोग करता है (संख्या और तार के मामले में):
संख्या के मामले में 44 बाइट्स
तार के मामले में + 24 बाइट्स
स्ट्रिंग की लंबाई (अंतिम एनयूएल चरित्र सहित)
(वे संख्याएँ PHP संस्करण के आधार पर बदल सकती हैं)
मेमोरी एलाइनमेंट के कारण आपको कई 4 बाइट्स तक राउंड करना होगा। यदि वैरिएबल वैश्विक स्थान पर है (फ़ंक्शन के अंदर नहीं), तो यह 64 और बाइट्स भी आवंटित करेगा।
इसलिए यदि आप इस पृष्ठ के अंदर किसी एक कोड का उपयोग करना चाहते हैं, तो आपको यह जांचना होगा कि कुछ सरल परीक्षण मामलों (स्ट्रिंग्स या संख्याओं) का उपयोग करने वाला परिणाम इस पोस्ट के हर एक संकेत ($ _GLOBAL सरणी) में उन आंकड़ों को ध्यान में रखते हुए मेल खाता है, पहला फ़ंक्शन कॉल, आउटपुट बफर, ...)