"वास्तविक उपयोग" के साथ memory_get_peak_usage ()


91

यदि PHP DOCS में real_usageतर्क सेट है true, तो यह सिस्टम से आवंटित मेमोरी का वास्तविक आकार प्राप्त करेगा। यदि यह है तो यह falseस्मृति को रिपोर्ट कर देगाemalloc()

इन 2 विकल्पों में से कौन सा अधिकतम वापस करता है। मेमोरी को php.ini में मेमोरी लिमिट वैल्यू के सापेक्ष आवंटित किया गया है?

मैं जानना चाहता हूं कि उस सीमा को हिट करने के लिए स्क्रिप्ट कितनी करीब थी।


8
मैं आपको php uk सम्मेलन 2013 के लिए जुलिएन पाउली youtube.com/watch?v=sm1HUrnsxLI द्वारा एक प्रस्तुति की ओर संकेत करना चाहूंगा , जहां वह इस बारे में बात करता है कि कैसे PHP के अंदर मेमोरी काम करती है।
मपरट

जवाबों:


136

ठीक है, एक सरल स्क्रिप्ट का उपयोग करके यह परीक्षण करने देता है:

ini_set('memory_limit', '1M');
$x = '';
while(true) {
  echo "not real: ".(memory_get_peak_usage(false)/1024/1024)." MiB\n";
  echo "real: ".(memory_get_peak_usage(true)/1024/1024)." MiB\n\n";
  $x .= str_repeat(' ', 1024*25); //store 25kb more to string
}

आउटपुट:

not real: 0.73469543457031 MiB
real: 0.75 MiB

not real: 0.75910949707031 MiB
real: 1 MiB

...

not real: 0.95442199707031 MiB
real: 1 MiB

not real: 0.97883605957031 MiB
real: 1 MiB

PHP Fatal error:  Allowed memory size of 1048576 bytes exhausted (tried to allocate 793601 bytes) in /home/niko/test.php on line 7

वास्तविक उपयोग की तरह लगता है कि सिस्टम से आबंटित मेमोरी है - जो कि स्क्रिप्ट द्वारा वर्तमान में आवश्यक से बड़ी बाल्टियों में आवंटित किया गया लगता है। (मैं प्रदर्शन कारणों से अनुमान लगाता हूं)। यह भी php प्रक्रिया का उपयोग करने वाली मेमोरी है।

$real_usage = falseउपयोग स्मृति उपयोग आप वास्तव में अपनी स्क्रिप्ट में प्रयोग किया जाता है, स्मृति की वास्तविक राशि Zend के स्मृति प्रबंधक द्वारा आवंटित नहीं है।

अधिक जानकारी के लिए यह प्रश्न पढ़ें ।

संक्षेप में: मेमोरी सीमा के कितने करीब होने के लिए, उपयोग करें $real_usage = true


5
Zend इंजन 256K चंक्स में मेमोरी आवंटित करता है। "वास्तविक उपयोग" मूल्य इन सभी विखंडू का योग है। यह वास्तव में मेमोरी थकावट त्रुटि को ट्रिगर करने के लिए उपयोग किया जाने वाला मूल्य है if (segment_size < true_size || heap->real_size + segment_size > heap->limit) { /* Memory limit overflow */:।
cleong

2
"वास्तविक नहीं" मान कॉल द्वारा अनुरोधित बाइट्स की संख्या का योग है emalloc(हेडर और मेमोरी संरेखण के लिए बाइट्स)। यह पहले से आवंटित सेगमेंट में शेष अंतरिक्ष में फिटिंग नहीं होने के कारण बर्बाद हुई मेमोरी को प्रतिबिंबित नहीं करता है। यदि आप (1024 * 256) बाइट्स और 2M सीमा आवंटित करने के लिए अपना उदाहरण बदलते हैं, तो दो का अंतर अधिक स्पष्ट हो जाएगा।
cleong

@Niko, आपने memory_get_page के बजाय memory_get_peak_usage का उपयोग क्यों किया? क्या हमें gc_disable () नहीं करना चाहिए और अधिक सटीक परिणाम प्राप्त करने के लिए memory_get_usage का उपयोग करना चाहिए?
पचेरियर

@ स्पेसियर का सवाल था कि स्क्रिप्ट की सीमा कितनी करीब है - उस चोटी के लिए समझ में आता है कि मैं कहूंगा
निको सैम्स

4
जैसा कि @ अंकोंग ने समझाया है, यह उत्तर वास्तव में गलत है, सभी उतार-चढ़ाव के बावजूद। memory_get_usage(true)रिटर्न मूल्य की तुलना में किया जाना चाहिए memory_limit। उदाहरण में दिया गया तरीका बहुत सरल है क्योंकि कोई "व्यर्थ" मेमोरी नहीं है। क्या होता है कि "वास्तविक" आवंटित मेमोरी को "1 MiB" से "1.25 MiB" तक बढ़ाने की आवश्यकता होती है और यही घातक त्रुटि को ट्रिगर करता है। । मेरे पास 120 मिब की मेमोरी सीमा वाली एक जटिल बैच स्क्रिप्ट है जिसमें "80 MiB" की "वास्तविक" आवंटित स्मृति नहीं है जब इसे निरस्त किया जाता है क्योंकि "वास्तविक" आवंटित स्मृति सीमा तक पहुंचती है।
मार्टिन प्रिक्रील

36

परिचय

आपको उपयोग करना चाहिए memory_get_usage(false)क्योंकि आप जो चाहते हैं वह मेमोरी है जिसका उपयोग मेमोरी आवंटित नहीं किया गया है।

क्या फर्क पड़ता है

आपके द्वारा आपके लिए भंडारण का Google Mailआवंटन किया जा सकता है 25MBलेकिन इसका मतलब यह नहीं है कि आपने इस समय क्या उपयोग किया है।

यह वही है जो PHP डॉक्टर कह रहा था

सिस्टम से आवंटित स्मृति का वास्तविक आकार प्राप्त करने के लिए इसे TRUE पर सेट करें। यदि सेट नहीं किया गया है या एफएएलएसई केवल एमालोक () द्वारा उपयोग की जाने वाली मेमोरी को सूचित करता है।

दोनों तर्क स्मृति सीमा के सापेक्ष आवंटित स्मृति को लौटा देंगे लेकिन मुख्य अंतर यह है:

memory_get_usage(false)emalloc()जब memory_get_usage(true)मील का पत्थर इस्तेमाल किया जाता है तो मेमोरी दें जो यहां मेमोरी माइल स्टोर का प्रदर्शन हो सकता है

मैं जानना चाहता हूं कि उस सीमा को हिट करने के लिए स्क्रिप्ट कितनी करीब थी।

यह कुछ गणित लेगा और केवल लूप या विशिष्ट उपयोग के मामलों में काम कर सकता है। मैंने ऐसा क्यों कहा?

कल्पना कीजिए

ini_set('memory_limit', '1M');
$data = str_repeat(' ', 1024 * 1024);

The above script would fail before you even get the chance to start start checking memory

जहाँ तक मुझे पता है एक ही रास्ता है कि मैं PHP के एक चर या विशिष्ट खंड के लिए उपयोग की जाने वाली मेमोरी की जाँच कर सकता हूँ:

$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;

स्पष्टीकरण देखें , लेकिन यदि आप किसी लूप या पुनरावर्ती फ़ंक्शन में हैं, तो आप अधिकतम मेमोरी उपयोग का उपयोग करके सुरक्षित रूप से अनुमान लगाने के लिए कर सकते हैं कि मेमोरी पीक कब तक पहुंच जाएगी।

उदाहरण

ini_set('memory_limit', '1M');

$memoryAvailable = filter_var(ini_get("memory_limit"), FILTER_SANITIZE_NUMBER_INT);
$memoryAvailable = $memoryAvailable * 1024 * 1024;

$peekPoint = 90; // 90%

$memoryStart = memory_get_peak_usage(false);
$memoryDiff = 0;

// Some stats
$stat = array(
        "HIGHEST_MEMORY" => 0,
        "HIGHEST_DIFF" => 0,
        "PERCENTAGE_BREAK" => 0,
        "AVERAGE" => array(),
        "LOOPS" => 0
);

$data = "";
$i = 0;
while ( true ) {
    $i ++;

    // Get used memory
    $memoryUsed = memory_get_peak_usage(false);

    // Get Diffrence
    $memoryDiff = $memoryUsed - $memoryStart;

    // Start memory Usage again
    $memoryStart = memory_get_peak_usage(false);

    // Gather some stats
    $stat['HIGHEST_MEMORY'] = $memoryUsed > $stat['HIGHEST_MEMORY'] ? $memoryUsed : $stat['HIGHEST_MEMORY'];
    $stat['HIGHEST_DIFF'] = $memoryDiff > $stat['HIGHEST_DIFF'] ? $memoryDiff : $stat['HIGHEST_DIFF'];
    $stat['AVERAGE'][] = $memoryDiff;
    $stat['LOOPS'] ++;
    $percentage = (($memoryUsed + $stat['HIGHEST_DIFF']) / $memoryAvailable) * 100;

    // var_dump($percentage, $memoryDiff);

    // Stop your scipt
    if ($percentage > $peekPoint) {

        print(sprintf("Stoped at: %0.2f", $percentage) . "%\n");
        $stat['AVERAGE'] = array_sum($stat['AVERAGE']) / count($stat['AVERAGE']);
        $stat = array_map(function ($v) {
            return sprintf("%0.2f", $v / (1024 * 1024));
        }, $stat);
        $stat['LOOPS'] = $i;
        $stat['PERCENTAGE_BREAK'] = sprintf("%0.2f", $percentage) . "%";
        echo json_encode($stat, 128);
        break;
    }

    $data .= str_repeat(' ', 1024 * 25); // 1kb every time
}

उत्पादन

Stoped at: 95.86%
{
    "HIGHEST_MEMORY": "0.71",
    "HIGHEST_DIFF": "0.24",
    "PERCENTAGE_BREAK": "95.86%",
    "AVERAGE": "0.04",
    "LOOPS": 11
}

लाइव डेमो

यह अभी भी विफल हो सकता है

यह विफल हो सकता है क्योंकि इसके बाद if ($percentage > $peekPoint) { भी अभी भी अतिरिक्त कार्य करने के लिए जोड़ने के साथ भी मेमोरी की खपत होती है

        print(sprintf("Stoped at: %0.2f", $percentage) . "%\n");
        $stat['AVERAGE'] = array_sum($stat['AVERAGE']) / count($stat['AVERAGE']);
        $stat = array_map(function ($v) {
            return sprintf("%0.2f", $v / (1024 * 1024));
        }, $stat);
        $stat['LOOPS'] = $i;
        $stat['PERCENTAGE_BREAK'] = sprintf("%0.2f", $percentage) . "%";
        echo json_encode($stat, 128);
        break;

If the memory to process this request is grater than the memory available the script would fail.

निष्कर्ष

इसका एक सही समाधान नहीं है, लेकिन अंतराल पर स्मृति की जांच करें और यदि इसकी अधिक मात्रा (जैसे 90%) exitझटपट दिखाई दे और फैंसी सामान छोड़ दें


है memory_limitढेर के बारे में विकल्प? या स्टैक?
योषा अलायूब

क्या होगा यदि मेरे पास समानांतर या कई अनुरोधों में दो स्क्रिप्ट हैं, di memory_get_usage () फ़ंक्शन उसी समय या केवल वास्तविक स्क्रिप्ट में निष्पादित उन सभी स्क्रिप्ट के लिए उपयोग की गई मेमोरी वापस करते हैं?
मोहम्मद यासीन CHABLI

7

real_usageझूठी रिपोर्ट आपके द्वारा उपयोग की गई स्क्रिप्ट का उपयोग करती है । यह दोनों में से अधिक सटीक होगा।

real_usageसच्ची रिपोर्ट आपकी स्क्रिप्ट को आवंटित मेमोरी को बताती है । यह दो में से उच्च होगा।

trueयदि मैं आपकी तुलना करने के लिए कोशिश कर रहा था तो मैं शायद इसका उपयोग करूँगा , क्योंकि आपकी स्क्रिप्ट को मेमोरी सीमा से अधिक आवंटित नहीं किया जाएगा, और जब तक यह चलता रहेगा (प्लस सभी अन्य स्क्रिप्ट) उस उपयोग से अधिक नहीं होगा।


1
यह बिल्कुल विपरीत है: falseवह मेमोरी जो स्क्रिप्ट का उपयोग किया जाता है , trueक्या मेमोरी आवंटित की जाती है
बेंजामिन

1
@ बैंजामिन हाँ, मुझे यकीन नहीं है कि मुझे ऐसा क्यों लगा कि यह गलत है। उम्म, तय हो गया।
ग्लिच डिज़ायर

2

PHP memory_get_usage के अनुसार

real_usage

अप्रयुक्त पृष्ठों सहित, सिस्टम से आवंटित कुल मेमोरी प्राप्त करने के लिए इसे TRUE पर सेट करें। यदि सेट या FALSE नहीं है, तो केवल उपयोग की गई मेमोरी की सूचना दी जाती है।

इसलिए आपकी स्क्रिप्ट द्वारा उपयोग की जाने वाली मेमोरी को प्राप्त करने के लिए आपको memory_get_usage () का उपयोग करना चाहिए क्योंकि डिफ़ॉल्ट real_usage गलत है।

यदि आप सिस्टम द्वारा आवंटित मेमोरी प्राप्त करना चाहते हैं, लेकिन इस बात की परवाह नहीं करते हैं कि वास्तव में कितना उपयोग किया गया था, तो memory_get_usage (true) का उपयोग करें;


-1
<!-- Print CPU memory and load -->
<?php
$output = shell_exec('free');
$data = substr($output,111,19);
echo $data;
echo file_get_contents('/proc/loadavg');
$load = sys_getloadavg();
$res = implode("",$load);
echo $res;
?>

1
Stackoverflow में आपका स्वागत है! क्या आप हमें बता सकते हैं कि उत्तर क्या है? न केवल कोड बल्कि यह भी कि आपने कैसे पता लगाया कि प्रश्न कैसे ठीक किया जाए। धन्यवाद!
गाइल्स हेइन्शच

हालांकि आपका जवाब कुछ संभावित उपयोगी जानकारी प्रदान कर सकता है, यह पूछे जाने वाले प्रश्न के लिए प्रासंगिक नहीं है। आप यह बताना चाहते हैं कि आपका उत्तर पूछे जाने वाले प्रश्न से कैसे संबंधित है।
मोरीतुर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.