[php] “실제 사용량”이있는 memory_get_peak_usage ()

real_usage인수가 truePHP DOCS 로 설정 되면 시스템에서 할당 된 실제 메모리 크기를 가져옵니다. 그것이 있다면 그것은 false보고 된 메모리를 얻을 것입니다emalloc()

이 두 가지 옵션 중 어느 것이 최대 값을 반환합니까? php.ini의 메모리 제한 값에 상대적으로 할당 된 메모리?

스크립트가 그 한계에 얼마나 근접했는지 알고 싶습니다.



답변

좋습니다. 간단한 스크립트를 사용하여 테스트 해 보겠습니다.

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사용은 당신이 실제로 스크립트에 사용되는 메모리 사용하지 젠드의 메모리 관리자에 의해 할당 된 메모리의 실제 양이다.

자세한 내용은 이 질문 을 읽으십시오 .

요컨대 : 메모리 한계에 얼마나 근접했는지 확인하려면 $real_usage = true


답변

소개

memory_get_usage(false)원하는 것은 할당 된 메모리가 아닌 사용 된 메모리이기 때문에 사용해야합니다 .

차이점이 뭐야

귀하 Google Mail가 귀하를 25MB위해 스토리지를 할당했을 수도 있지만 이것이 현재 사용한 스토리지임을 의미하지는 않습니다.

이것이 바로 PHP 문서가 말한 내용입니다.

시스템에서 할당 된 실제 메모리 크기를 얻으려면 TRUE로 설정하십시오. 설정하지 않거나 FALSE 인 경우 emalloc ()에서 사용하는 메모리 만보고됩니다.

두 인수 모두 메모리 제한에 상대적으로 할당 된 메모리를 반환하지만 주요 차이점은 다음과 같습니다.

memory_get_usage(false)여기에서 데모가 될 수있는 이정표를 반환 하는 emalloc()동안 사용 된 메모리를 제공합니다. Memory Mile Storememory_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.

결론

완벽한 솔루션은 아니지만 간격을두고 메모리를 확인하고 exit즉시 엿보기 (예 : 90 %)를 초과하는지 확인 하고 멋진 물건을 남겨 둡니다.


답변

real_usagefalse는 스크립트가 사용한 사용량을보고합니다 . 이것은 둘 중 더 정확할 것입니다.

real_usagetrue는 스크립트에 할당 된 메모리를보고합니다 . 이것은 둘 중 더 높을 것입니다.

아마 사용하십시오 true스크립트가 더 많은 메모리 제한보다 할당되지 않을 것 같이 내가 비교하려고 한 경우, 그리고 그것이 (및 다른 모든 스크립트) 그 사용량을 초과하지 않은 것처럼 계속 실행됩니다.


답변

PHP memory_get_usage에 따라

real_usage

사용하지 않는 페이지를 포함하여 시스템에서 할당 된 총 메모리를 얻으려면 이것을 TRUE로 설정하십시오. 설정되지 않거나 FALSE 인 경우 사용 된 메모리 만보고됩니다.

따라서 스크립트에서 사용하는 메모리를 얻으려면 기본 real_usage가 false이므로 memory_get_usage ()를 사용해야합니다.

시스템에 의해 할당 된 메모리를 얻고 싶지만 실제로 얼마나 많이 사용되었는지 신경 쓰지 않는다면 memory_get_usage (true);


답변

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


답변