"বাস্তব ব্যবহার" সহ মেমরি_জেট_পিএক_উসেজ ()


94

যদি তর্কটি পিএইচপি ডকসে real_usageসেট করা থাকে trueতবে এটি সিস্টেম থেকে বরাদ্দকৃত মেমরির আসল আকার পাবে। যদি তা হয় তবে এটি falseমেমোরি দ্বারা রিপোর্ট করা হবেemalloc()

এই 2 বিকল্পগুলির মধ্যে কোনটি সর্বোচ্চটি প্রদান করে। php.ini এ মেমরি সীমা মানের তুলনায় বরাদ্দ?

আমি জানতে চাই স্ক্রিপ্টটি কতটা সীমাবদ্ধ হয়েছিল hit


8
আমি আপনাকে পিএইচপি ইউ কে সম্মেলন ২০১৩-এর জুলিয়েন পাওলি ইউটিউব. com/ watch? v = sm1HUrnsxLI এর একটি উপস্থাপনাটির দিকে ইঙ্গিত করতে চাই , যেখানে তিনি পিএইচপি-র ভিতরে স্মৃতি কীভাবে কাজ করে সে সম্পর্কে আলোচনা করেছেন।
এমপিরাট

আরো দেখুন stackoverflow.com/a/7234026/632951
Pacerier

উত্তর:


138

ঠিক আছে, একটি সাধারণ স্ক্রিপ্ট ব্যবহার করে এটি পরীক্ষা করি:

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

বাস্তব ব্যবহারের মতো মনে হচ্ছে সিস্টেম থেকে বরাদ্দ হওয়া মেমরি - যা বর্তমানে স্ক্রিপ্টের চেয়ে প্রয়োজনের চেয়ে বড় বালতিগুলিতে বরাদ্দ পেয়েছে বলে মনে হয়। (আমি পারফরম্যান্স কারণে অনুমান)। এটি পিএইচপি প্রক্রিয়া ব্যবহার করে এমন মেমরিও।

$real_usage = falseব্যবহার করা মেমোরি ব্যবহার আপনি আসলে আপনার স্ক্রিপ্টের ব্যবহার করা, মেমরি প্রকৃত পরিমাণ পার্সি-জাতির প্রাচীন শাস্ত্রগ্রন্থ স্মৃতিতে ম্যানেজার দ্বারা বরাদ্দ নয়।

আরও তথ্যের জন্য এই প্রশ্নটি পড়ুন ।

সংক্ষেপে: আপনি মেমরির সীমাটির কত কাছাকাছি রয়েছেন তা ব্যবহার করতে $real_usage = true


4
জেন্ড ইঞ্জিন 256 কে অংশে মেমরি বরাদ্দ করে। "আসল ব্যবহার" মান এই সমস্ত খণ্ডের যোগফল। এটা আসলে মেমরির নিঃশেষিত ত্রুটি আরম্ভ করতে ব্যবহৃত মান: if (segment_size < true_size || heap->real_size + segment_size > heap->limit) { /* Memory limit overflow */
ক্লোং

4
"আসল নয়" মানটি কল দ্বারা অনুরোধ করা বাইটের সংখ্যার যোগফল emalloc(অতিরিক্ত শিরোনাম এবং মেমরির সারিবদ্ধকরণের জন্য বাইট)। এটি ইতিমধ্যে বরাদ্দকৃত অংশগুলিতে অবশিষ্ট জায়গাগুলিতে ব্লক না লাগায় মেমরির অপচয় হওয়া প্রতিফলিত করে না। আপনি যদি উদাহরণটি (1024 * 256) বাইট এবং 2 এম সীমাতে বরাদ্দ করতে পরিবর্তন করেন তবে দুটির পার্থক্য আরও প্রকট হয়ে উঠবে।
ক্লোং

@ নিকো, কেন আপনি মেমরি_জেট_উসেজের পরিবর্তে মেমরি_জেট_পিকে_ব্যবহার করলেন? আরও সঠিক ফলাফল পেতে আমরা কি gc_disable () এবং মেমোরি_সেজ_ব্যবহার ব্যবহার করা উচিত না?
পেসারিয়ার

@ পেসিয়ার প্রশ্নটি ছিল স্ক্রিপ্টটির সীমা কতটা কাছাকাছি চলে আসবে - সেই শীর্ষটি বোধগম্য হওয়ার জন্য আমি বলতে পারি
নিকো সামস

4
@ ক্লাং যেমন ব্যাখ্যা করেছেন, সমস্ত উত্সাহ থাকা সত্ত্বেও এই উত্তরটি আসলে ভুল। memory_get_usage(true)আয় মান তুলনায় দিতে হবে memory_limit। উত্তরে প্রদত্ত উদাহরণটি খুব সহজ, কারণ সেখানে কোনও "নষ্ট" মেমরি নেই What যা ঘটেছিল তা হল "আসল" বরাদ্দ হওয়া মেমরিটি "1 এমআইবি" থেকে "1.25 মাইবি" বাড়ানো দরকার এবং এটিই মারাত্মক ত্রুটিটিকে ট্রিগার করে that .আমার একটি জটিল ব্যাচের স্ক্রিপ্ট রয়েছে যা মেমরির সীমাবদ্ধতা রয়েছে 120 মাইবি যা কেবল "80
এমআইবি

37

ভূমিকা

আপনার ব্যবহার করা উচিত memory_get_usage(false)কারণ আপনি যা চান তা মেমরির বরাদ্দ নয় used

কি পার্থক্য

আপনার Google Mailসম্ভবত আপনার 25MBজন্য সঞ্চয়স্থান বরাদ্দ রয়েছে তবে এর অর্থ এই নয় যে আপনি এই মুহুর্তে ব্যবহার করেছেন।

এটি ঠিক পিএইচপি ডক বলছিল

সিস্টেম থেকে বরাদ্দ মেমরির আসল আকার পেতে এটি সত্যতে সেট করুন। সেট না করা থাকলে বা মিথ্যা না হলে কেবল ইমলোক () দ্বারা ব্যবহৃত মেমরিটি রিপোর্ট করা হয়।

উভয় যুক্তি মেমরি সীমাটির তুলনায় বরাদ্দ মেমরি ফিরিয়ে দেবে তবে মূল পার্থক্যটি হ'ল:

memory_get_usage(false)এখানে মেমোরি মাইল স্টোর প্রদর্শিত হতে পারে যা মাইলফলক প্রত্যাবর্তনের emalloc()সময় দ্বারা ব্যবহৃত মেমরি দিনmemory_get_usage(true)

আমি জানতে চাই স্ক্রিপ্টটি কতটা সীমাবদ্ধ হয়েছিল hit

এটি কিছু গণিত নিতে পারে এবং কেবল লুপ বা নির্দিষ্ট ব্যবহারের ক্ষেত্রে কাজ করতে পারে। আমি কেন এমন কথা বললাম?

কল্পনা করুন

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

যতদূর আমি জানি একমাত্র উপায় হিসাবে আমি পিএইচপি এর পরিবর্তনশীল বা নির্দিষ্ট বিভাগের জন্য ব্যবহৃত মেমরিটি পরীক্ষা করতে পারি:

$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.

উপসংহার

এটি একটি নিখুঁত সমাধান নয় তবে বিরতিতে মেমরি পরীক্ষা করে নিন এবং যদি এটি exitতাত্ক্ষণিক উঁকি দেওয়া হয় (যেমন 90%) এবং অভিনব জিনিসগুলি ছেড়ে যান


কি memory_limitগাদা সম্পর্কে বিকল্প? বা স্ট্যাক?
ইউশা আলেয়াউব

যদি আমার সমান্তরাল বা বহু অনুরোধে দুটি স্ক্রিপ্ট থাকে তবে মেমরি_জেট_সেজ () ফাংশনটি একই সময়ে কার্যকর হওয়া সমস্ত স্ক্রিপ্টের জন্য ব্যবহৃত স্মৃতি বা কেবল প্রকৃত স্ক্রিপ্টটি ফিরিয়ে দেয়?
মোহাম্মদ ইয়াসাইন চাবলি

7

real_usageআপনার স্ক্রিপ্ট ব্যবহৃত মিথ্যা রিপোর্ট । এই দুটি আরও সঠিক হবে।

real_usageসত্য আপনার স্ক্রিপ্ট বরাদ্দ মেমরি । এই দু'জনের চেয়ে বেশি হবে।

আমি trueতুলনা করার চেষ্টা করছিলাম যদি আমি সম্ভবত ব্যবহার করতাম , কারণ আপনার স্ক্রিপ্টটি কখনই মেমরির সীমা ছাড়িয়ে বেশি বরাদ্দ করা হত না এবং যতক্ষণ না এটি ব্যবহার করা হয় (প্লাস অন্যান্য সমস্ত স্ক্রিপ্টগুলি) ব্যবহারটি অতিক্রম করে না would


4
ঠিক বিপরীত আছে: falseমেমরির স্ক্রিপ্ট হয় ব্যবহৃত , trueস্মৃতি বরাদ্দ
বেনিয়ামিন

4
@ বেনজামিন হ্যাঁ, কেন আমি এত অন্ধভাবে ভুল পেয়েছি তা নিশ্চিত নয়। উম্ম, স্থির।
গ্লাচ ডিজায়ার

2

পিএইচপি মেমরি_জেট_উসেজ অনুযায়ী

রিয়েল_সেজ

অব্যবহৃত পৃষ্ঠাগুলি সহ সিস্টেম থেকে বরাদ্দকৃত মোট স্মৃতি পেতে এটি সত্যে সেট করুন। যদি সেট না হয় বা মিথ্যা হয় তবে কেবল ব্যবহৃত মেমরিটিই রিপোর্ট করা হয়।

সুতরাং আপনার স্ক্রিপ্টের দ্বারা মেমরিটি ব্যবহার করতে আপনার ডিফল্ট রিয়েল_সেজ মিথ্যা হিসাবে মেমরি_জেট_উসেজ () ব্যবহার করা উচিত।

আপনি যদি সিস্টেমের দ্বারা বরাদ্দকৃত স্মৃতি পেতে চান তবে বাস্তবে কতটা ব্যবহৃত হয়েছিল তা যত্নশীল না করে মেমরি_জেট_সেজ (সত্য) ব্যবহার করুন;


0
<!-- 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;
?>

4
স্ট্যাকওভারফ্লোতে স্বাগতম! আপনি কি দয়া করে আমাদের উত্তর দিতে পারেন? কেবল কোডটিই নয় আপনি কীভাবে প্রশ্নটি ঠিক করবেন তা কীভাবে নির্ধারণ করেছেন। ধন্যবাদ!
গিলস হাইনেস

যদিও আপনার উত্তরটি কিছু সম্ভাব্য দরকারী তথ্য সরবরাহ করতে পারে, এটি জিজ্ঞাসা করা প্রশ্নের সাথে প্রাসঙ্গিক নয়। আপনার উত্তর জিজ্ঞাসা করা প্রশ্নের সাথে কীভাবে সম্পর্কিত তা আপনি ব্যাখ্যা করতে চাইতে পারেন।
মরিটুর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.