programing

변수의 메모리 공간(크기)을 판별하는 방법

firstcheck 2022. 10. 18. 21:48
반응형

변수의 메모리 공간(크기)을 판별하는 방법

PHP(또는 PHP 확장자)에는 주어진 변수가 사용하는 메모리의 양을 알아내는 함수가 있습니까? sizeof요소/속성의 개수만 알 수 있습니다.

memory_get_usage스크립트 전체에서 사용되는 메모리 크기를 알 수 있습니다.단일 변수에 대해 이 작업을 수행할 수 있는 방법이 있습니까?

이것은 개발 머신 상에 있으므로 확장 또는 디버깅툴을 로드할 수 있습니다.

을 직접 수 있는 제안한 대로 할 수 .memory_get_usage이렇게 하면 할당된 메모리의 총량이 반환되므로 회피책을 사용하여 단일 변수의 사용률을 확인할 수 있습니다.이이좀 、 터잘지,,, 、 잘잘야거거거 。

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

이 방법은 결코 신뢰할 수 있는 방법이 아닙니다.변수를 할당하는 동안 다른 어떤 것도 메모리에 영향을 주지 않기 때문에 이 방법은 근사치로만 사용해야 합니다.

함수 내부에 변수의 복사본을 만들고 사용된 메모리를 측정하여 실제로 함수를 설정할 수 있습니다.테스트해 본 적은 없지만 원칙적으로 문제될 것은 없습니다.

function sizeofvar($var) {
    $start_memory = memory_get_usage();
    $tmp = unserialize(serialize($var));
    return memory_get_usage() - $start_memory;
}

메모리 프로파일러가 필요할 수 있습니다.SO에 대한 정보를 수집했지만, 당신에게도 도움이 될 수 있는 중요한 것을 복사했습니다.

아시다시피 Xdebug는 2.* 버전 이후 메모리 프로파일링 지원을 중단했습니다.http://www.xdebug.org/updates.php 에서 "functions" 문자열을 검색하십시오.

기능 삭제

메모리 프로파일링이 올바르게 동작하지 않기 때문에, 서포트 해제.

기타 프로파일러 옵션

php-memory-profiler

https://github.com/arnaud-lb/php-memory-profiler 를 참조해 주세요.Ubuntu 서버에서 이 기능을 활성화하기 위해 다음과 같이 했습니다.

sudo apt-get install libjudy-dev libjudydebian1
sudo pecl install memprof
echo "extension=memprof.so" > /etc/php5/mods-available/memprof.ini
sudo php5enmod memprof
service apache2 restart

그리고 내 코드로:

<?php
memprof_enable();
// do your stuff
memprof_dump_callgrind(fopen("/tmp/callgrind.out", "w"));

으로 '열다'를 .callgrind.outKCachegrind로 파일하다

Google gperftools 사용(권장)

먼저 여기서 최신 패키지를 다운로드하여 Google gperftools를 설치합니다.https://code.google.com/p/gperftools/

그럼 항상 그렇듯이:

sudo apt-get update
sudo apt-get install libunwind-dev -y
./configure
make
make install

이제 코드 입력:

memprof_enable();

// do your magic

memprof_dump_pprof(fopen("/tmp/profile.heap", "w"));

그런 다음 터미널을 열고 다음을 실행합니다.

pprof --web /tmp/profile.heap

pprof는 기존 브라우저 세션에 다음과 같은 새 창을 만듭니다.

memprof 및 gperftools를 사용한 PHP 메모리 프로파일링

Xhprof + Xhgui (CPU와 메모리 양쪽 프로파일링에 최적)

XhprofXhgui를 사용하면 CPU 사용률도 프로파일링할 수 있습니다.또한 현재 문제가 있다면 메모리 사용률만 프로파일링할 수 있습니다.이 솔루션은 매우 완벽한 솔루션으로, 완전한 제어를 제공하며 로그는 mongo 또는 파일 시스템에 모두 쓸 수 있습니다.

자세한 것은, 여기를 참조해 주세요.

블랙파이어

Blackfire는 SensioLabs의 PHP 프로파일러로 Symfony2 guys https://blackfire.io/

pupphpet을 사용하여 가상 머신을 셋업하는 경우 지원되는 가상 머신이 있으면 매우 편리합니다;-)

Xdebug 및 메모리 사용량 추적

XDEBUG2는 PHP의 확장입니다.Xdebug를 사용하면 파라미터와 반환값을 포함한 모든 함수 호출을 다른 형식의 파일에 기록할 수 있습니다.출력 형식은 3가지가 있습니다.하나는 사람이 읽을 수 있는 트레이스이고, 다른 하나는 해석하기 쉬워 컴퓨터 프로그램에 더 적합하며, 마지막 하나는 트레이스 포맷에 HTML을 사용합니다.설정을 사용하여 두 가지 형식을 전환할 수 있습니다.예시는 이쪽에서 보실 수 있습니다.

포프

forp 단순하고 방해되지 않으며 운영 지향적인 PHP 프로파일러입니다.기능에는 다음과 같은 것이 있습니다.

  • 각 기능에 대해 할당된 메모리와 시간 측정

  • CPU 사용률

  • 함수 호출의 파일 및 회선 번호

  • Google의 Trace Event 형식으로 출력

  • 함수의 캡션

  • 함수의 그룹화

  • 함수의 에일리어스(어나니머스 함수의 경우)

DBG

DBG는 완전한 기능을 갖춘 php 디버거로, php 스크립트를 디버깅하는 데 도움이 되는 대화형 도구입니다.운영 및/또는 개발 WEB 서버에서 작동하며 IDE 또는 콘솔에서 로컬 또는 원격으로 스크립트를 디버깅할 수 있습니다. 기능은 다음과 같습니다.

  • 원격 및 로컬 디버깅

  • 명시적이고 암묵적인 액티베이션

  • 콜 스택(함수 콜, 다이내믹 메서드 및 스태틱 메서드콜 포함), 파라미터

  • 대응하는 (내포된) 장소의 변수를 평가하는 기능을 갖춘 콜스택을 통한 네비게이션

  • 스텝인/스텝아웃/스텝오버/커서로 실행 기능

  • 조건부 중단점

  • 글로벌 중단점

  • 오류 및 경고 로깅

  • 병렬 디버깅을 위한 여러 동시 세션

  • GUI 및 CLI 프론트 엔드 지원

  • IPv6 및 IPv4 네트워크 지원

  • 디버거에 의해 전송되는 모든 데이터는 SSL로 선택적으로 보호 가능

아니, 없어.그러나 근사치를 위해 결과를 확인하고 확인할 수 있습니다.

Tatu Ulmanens의 대답:

$start_memory차지하다PHP_INT_SIZE * 8를 참조해 주세요.

따라서 전체 기능은 다음과 같습니다.

function sizeofvar($var) {
    $start_memory = memory_get_usage();
    $var = unserialize(serialize($var));
    return memory_get_usage() - $start_memory - PHP_INT_SIZE * 8;
}

덧붙여서 죄송합니다만, 아직 답변에 대해서는 코멘트를 드릴 말씀이 없습니다.

업데이트: *8은 정의되어 있지 않습니다.php 버전에 따라 다르지만 64/32비트에 따라 다를 수 있습니다.

두 변수가 메모리 내에서 동일한 할당된 공간을 공유할 수 있으므로 변수의 정확한 설치 공간을 소급하여 계산할 수 없습니다.

두 어레이 간에 메모리를 공유해 보겠습니다.두 번째 어레이를 할당하는 데 첫 번째 어레이의 메모리 절반의 비용이 소요됩니다.첫 번째 메모리 설정을 해제해도 두 번째 메모리에서는 거의 모든 메모리가 사용됩니다.

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)

따라서 첫 번째 어레이를 설정 해제하면 false가 되기 때문에 두 번째 어레이가 메모리의 절반을 사용한다는 결론을 내릴 수 없습니다.

메모리가 PHP에서 어떻게 할당되고 어떤 용도로 사용되는지에 대한 자세한 내용은 다음 문서를 참조하십시오.실제로 PHP 어레이(및 값)의 크기는 얼마나 됩니까? (힌트: BIG!)

PHP 문서의 참조 카운트 기본 사항에도 메모리 사용에 대한 많은 정보가 포함되어 있으며, 공유 데이터 세그먼트에 대한 참조가 카운트됩니다.

여기에 나와 있는 다른 솔루션들은 근사치에는 좋지만 PHP 메모리의 미묘한 관리에는 어느 누구도 대처할 수 없습니다.

  1. 새로 할당된 공간 계산

후 " "를 .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()하다

위의 예와 같이 에코를 할 경우 출력 버퍼를 열 때 필요한 계정 메모리를 피하기 위해 출력 버퍼를 이미 열어야 합니다.

  1. 필요한 공간 계산

함수를 사용하여 변수 복사본을 저장하는 데 필요한 공간을 계산하려면 다음 코드가 다양한 최적화를 처리합니다.

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

변수 이름의 크기는 할당된 메모리에서 중요합니다.

  1. 코드를 체크하세요!!

변수는 PHP 소스 코드에서 사용되는 내부 C 구조에 의해 정의된 기본 크기를 가집니다.이 크기는 숫자의 경우 변동하지 않습니다.문자열의 경우 문자열 길이가 추가됩니다.

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바이트

+ 문자열 길이(최종 NUL 문자 포함)

(이 숫자는 PHP 버전에 따라 변경될 수 있습니다.)

메모리 정렬 때문에 최대 4바이트의 배수를 반올림해야 합니다.변수가 글로벌 공간(함수 내부가 아님)에 있는 경우 64바이트도 더 할당됩니다.

따라서 이 페이지 내의 코드 중 하나를 사용하려면 간단한 테스트 케이스(스트링 또는 숫자)를 사용한 결과가 이 게시물의 모든 표시($_GLOBAL 배열, first function call, output buffer 등)를 고려하여 해당 데이터와 일치하는지 확인해야 합니다.

참조:

단, 특정 변수의 메모리 사용량은 제공되지 않습니다.단, 변수 할당 전후에 이들 함수에 콜을 발신하여 값을 비교할 수 있습니다.그러면 사용된 기억을 알 수 있을 겁니다.

PECL 확장 Memtrack도 참조할 수 있습니다.다만, 이 메뉴얼은 다소 부족하지만, 실제로는 존재하지 않습니다.

콜백 반환값의 메모리 차이를 계산하도록 선택할 수 있습니다.PHP 5.3+에서 사용할 수 있는 보다 우아한 솔루션입니다.

function calculateFootprint($callback) {
    $startMemory = memory_get_usage();
    $result = call_user_func($callback);
    return memory_get_usage() - $startMemory;
}

$memoryFootprint = calculateFootprint(
    function() {
        return range(1, 1000000);
    }
);

echo ($memoryFootprint / (1024 * 1024)) . ' MB' . PHP_EOL;

비슷한 문제가 있었는데, 제가 사용한 해결책은 변수를 파일에 쓴 후 filesize()를 실행하는 것이었습니다.대략 다음과 같습니다(테스트되지 않은 코드):

function getVariableSize ( $foo ) 
{
    $tmpfile = "temp-" . microtime(true) . ".txt";
    file_put_contents($tmpfile, $foo);
    $size = filesize($tmpfile);
    unlink($tmpfile);
    return $size;
}

이 솔루션은 디스크 IO를 수반하기 때문에 그다지 빠르지는 않지만 memory_get_usage보다 훨씬 정확한 기능을 제공합니다.얼마나 정확해야 하느냐에 따라 다르죠

다음 스크립트는 단일 변수의 총 메모리 사용량을 보여 줍니다.

function getVariableUsage($var) {
  $total_memory = memory_get_usage();
  $tmp = unserialize(serialize($var));
  return memory_get_usage() - $total_memory; 
}

$var = "Hey, what's you doing?";
echo getVariableUsage($var);

이것 좀 봐

http://www.phpzag.com/how-much-memory-do-php-variables-use/

시도하지 않았지만 xdebug.collect_assignments를 사용하는 Xdebug 트레이스로 충분할 수 있습니다.

언급URL : https://stackoverflow.com/questions/2192657/how-to-determine-the-memory-footprint-size-of-a-variable

반응형