2013-02-14 4 views
1

일부 PHP 프로세스의 메모리 사용법을 이해하려고합니다. get_memory_usage()pmap을 모두 사용해 보았지만 그 결과는 약 1 배 정도 벗어났습니다. 나는 memory_get_usage()memory_get_usage(true)뿐 아니라 memory_get_peak_usage(true)도 시도했지만, 심지어는 memory_get_peak_usage(true) (세 가지 종류 중 가장 큰 것)조차도 pmap을 통해보고되는 것과는 큰 차이가 있습니다. pmap -d PID의 전형적인 결과가 같은 것을 제공하는 반면, 내 PHP 스크립트 내의 모든 분 1.75MB 및 3.5MB 사이의 범위 값을 반환 memory_get_peak_usage(true)를 호출 구체적memory_get_usage() 및 pmap 이해하기

:

... 

b7839000  4 r---- 0000000000008000 0ca:00060 libcrypt-2.11.1.so 
b783a000  4 rw--- 0000000000009000 0ca:00060 libcrypt-2.11.1.so 
b783b000  156 rw--- 0000000000000000 000:00000 [ anon ] 
b7864000  8 rw--- 0000000000000000 000:00000 [ anon ] 
b7867000  12 r-x-- 0000000000000000 0ca:00060 libgpg-error.so.0.4.0 
b786a000  4 r---- 0000000000002000 0ca:00060 libgpg-error.so.0.4.0 
b786b000  4 rw--- 0000000000003000 0ca:00060 libgpg-error.so.0.4.0 
b786c000  4 r---- 0000000000000000 000:00000 [ anon ] 
b786d000  16 rw--- 0000000000000000 000:00000 [ anon ] 
b7871000  108 r-x-- 0000000000000000 0ca:00060 ld-2.11.1.so 
b788c000  4 r---- 000000000001a000 0ca:00060 ld-2.11.1.so 
b788d000  4 rw--- 000000000001b000 0ca:00060 ld-2.11.1.so 
bffc7000  136 rw--- 0000000000000000 000:00000 [ stack ] 
f57fe000  4 r-x-- 0000000000000000 000:00000 [ anon ] 
mapped: 32740K writeable/private: 13116K shared: 28K 

만약 내가 제대로 이해하고, 쓰기 가능한/비공개 그림은 프로세스에서 독점적으로 사용되는 메모리이기 때문에 가장 적합한 수치입니다. 거의 13MB는 memory_get_peak_usage(true)에 의해보고 된 금액과는 거리가 있습니다. 누군가가 불일치를 설명해 주시겠습니까?

답변

0

바이트와 비트의 합은 10입니다. 따라서 1.3 MBytes = 13MBits

+0

감사합니다. 실제로 1 바이트 = 8 비트,하지만 나는 이것을 두 번 확인했다. pmap 매뉴얼 (http://linux.die.net/man/1/pmap)에 따르면 메모리 사용량은 킬로바이트 단위로보고됩니다. memory_get_peak_usage()는 바이트 단위로 사용량/할당량을 출력합니다.이 용량은 내가 어딘가에서 훔친 함수를 사용하여 메가 바이트로 변환되었습니다. [$ exp = floor (log ($ bytes)/log (1024)); $ bytes/pow (1024, floor ($ exp));] ... Google의 편리한 디스크 저장소 변환기를 사용하여 일부 값을 두 번 확인한 후. 그래서 그게 범인이라고 생각하지 않습니다. 하지만 불일치가 얼마나 가까운 지 의심 스럽습니다. – robguinness

+0

그래, 나는 내가 항상 기억할 수있는 단순함을 위해 10의 요소에서 항상 작동하는 정확한 수치를 찾지 않았다. 기본 8 내 강한 장점은 아니지만 나는 두렵다. 바이트를 kb로 변환하면 바이트/1024로 변환 한 다음 kb/1024로 변환하면 너무 복잡해지기가 필요 없습니다. 방정식을 통해 mb 그림을 얻습니다. – Dave

+0

13116K = 12.8 mb 이는 처음에 기본 10보다 기본 8 변환에 더 가깝습니다. 나는 여러분에게 뭔가 다른 것을 알려주지 만 숫자가 아닌 비트 단위로 반환되는 수치 중 하나에 돈을 넣을 것입니다! – Dave

3

제 생각에 memory_get_peak_usage()은 스크립트에서 사용하는 메모리 양을 반환합니다. PHP의 오버 헤드를 포함하지 않습니다.

PHP 스크립트에 할당 된 최대 메모리 (바이트)를 반환합니다.

PHP가 사용하는 메모리를 줄이면 더 적은 확장명으로 컴파일 할 수 있습니다.

PHP 자체는 특히 기본 확장자가있는 대형 응용 프로그램입니다. 우리는 (PHP 개발자로서) simplexml_load_string()과 같은 간단한 코드를 작성하고 마술이 일어나는 것을 보게됩니다. 그러나 그 마법을 강화하는 코드는 메모리 어딘가에서 시작됩니다. phpinfo()의 출력을 보면 얼마나 많은 확장 프로그램이 설치되어 있는지 알 수 있습니다. PHP 내부에서 PHP를 가져 와서 OPCODE로 변환 한 코드를 작성한 다음 해당 opcode를 실행하는 코드를 작성합니다. 실행중인 PHP의 각 인스턴스는 그 오버 헤드를 수행합니다.

이 메모리 사용은 분명히 중요하지 않지만 예상되는 내용입니다. 들어오는 GET/POST/FILES를 처리하기 위해 모든 코드를 작성해야만한다면 XML, 파일 및 스트림 마술 등을 관리해야합니다. 메모리 사용량이 빠르게 증가합니다.

결과적으로 일반적인 실행 기술은 실행 파일 크기를 줄이기 위해 불필요한 모든 확장을 제거하는 것입니다. 메모리가 부족한 서버 (대부분로드 된 서버)의 경우 약간의 확장을 제거하고 메모리 사용량을 9에서 7 megs로 줄이면 더 많은 아파치 작업자가 실행됩니다.

이 오버 헤드는 각 실행이 실제로 실행중인 PHP의 개별 사본이기 때문에 공유되지 않습니다. 스레드 세이프 빌드를 사용하여 번갈아 가며 사용할 수 있지만 모든 PHP 확장이 스레드로부터 안전하지는 않습니다.

확장 프로그램 제거 사용중인 기능을 살펴보십시오. mysqli_*? xml_*? 기타또한 PHP가 구축되는 방법을 살펴, 여기 내 구성 라인이다 :

Configure Command => './configure' '--with-apxs2=/usr/local/apache2/bin/apxs' '--with-mysql=mysqlnd' '--with-gd' '--enable-soap' '--with-libxml-dir=/usr/lib/' '--with-mysql-sock=/tmp' '--with-tidy' '--with-jpeg-dir=/usr/lib/' '--with-xsl' '--with-curl' '--with-zlib' '--enable-gd-native-ttf' '--with-openssl' '--with-mcrypt' '--with-pdo-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-bz2' '--enable-bcmath'

I 메모리를 도용 한 경우 나 명시 적으로, (기본 확장을 제거하기 위해) ./configure --disable-all와 PHP를 구축만을 추가하여 시작할 것 내가 사용했던 확장 기능. 더 이상 내 코드에 libxml을 사용하지 않고 soap을 사용하지 않기 때문에 그 비트를 삭제할 수 있습니다. 내 tidy 작업을 기어 맨 작업자와 명령 줄에 아웃소싱 할 수 있으므로 그 작업도 수행 할 것입니다. 그럼 내 코드를 (여기에 단위 테스트를하는 것이 환상적 일 것입니다) 실행하고 파산을보고. 필요한 확장자로 PHP를 다시 빌드하고, 헹구고 반복하십시오. 프로덕션 환경에서이 작업을 수행하지 않거나 Bad Time을 사용하게 될 것입니다.

+0

나는 당신이 말하는 것에 진실이 있다고 생각하지만 오버 헤드는 모든 PHP 프로세스에 의해 공유되어서는 안된다? pmap의 출력을 이해하면 쓰기 가능/비공개는 프로세스가 독점적으로 사용하는 메모리 공간 만 참조합니다. 게다가, 나는 ~ 40 개의 프로세스가 동시에 실행되고, 사용 된 전체 메모리는 대략 275-300MB입니다. 이것은 각 프로세스가 7-7.5MB를 사용한다는 것을 의미합니다. 그것은 memory_get_peak_usage()에 의해보고 된 것에서 여전히 먼 길입니다. 이 다른 메모리는 어디에 사용됩니까? 리눅스에서 자원을 사용하는 각 활동은 프로세스로 식별됩니다. – robguinness

+0

죄송합니다.이 내용을 두 가지 의견으로 구분해야합니다. 그냥 추가하고 싶었 :이 "오버 헤드"에 기여하는 프로세스는 어디에 있습니까? ps aux를 실행하면 | grep php 내 스크립트의 인스턴스 만 ~ 40 개만 표시됩니다. 이 오버 헤드가 다른 프로세스에 숨어 있습니까? 그렇다면 어떤 프로세스에 숨어 있습니까? – robguinness

+0

자세한 내용이 포함 된 연장 된 게시물 – preinheimer