programing

치명적인 오류:메모리는 부족하지만 메모리는 충분히 있다(PHP)

javaba 2022. 10. 6. 21:18
반응형

치명적인 오류:메모리는 부족하지만 메모리는 충분히 있다(PHP)

질문이 점점 길어지고 있기 때문에, 저는 문제를 더 좋게, 더 짧게 다시 쓰기로 결심했습니다.

저는 8GB 메모리를 탑재한 전용 서버에서 웹사이트를 운영하고 있습니다.php.ini 설정에서 메모리 제한을 높여야 한다는 것을 충분히 알고 있습니다.128M에서 256M, -1로 설정했습니다.여전히 문제는 끈기다.

치명적인 오류:D:\www\football\views\main에서 메모리 부족(할당 786432)(24576바이트 할당 시도)81행의 php

메모리 부족은 786432바이트만 할당되어 있고 24576바이트가 더 필요하기 때문에 의미가 없습니다.

786432 바이트는 768 킬로바이트에 불과하며 상당히 작습니다.

힌트

  • 에러는 랜덤 회선상에서 발생합니다.81번 줄에서 항상 오류가 발생하는 것은 아닙니다.
  • 피크 타임에 Apache는 약 500MB의 메모리만 사용합니다.아직 6GB가 남았습니다.
  • 무한 루프는 없습니다.
  • 이 스크립트는 1,042,424바이트가 소요됩니다.이 번호 가져오기echo memory_get_peak_usage();
  • MySQL의 결과 집합이 작습니다(최대 12개의 행, 순수 텍스트, BLOB 데이터 없음).
  • (중요) Apache를 이틀에 한 번 재시작하면 오류가 사라집니다.일반적으로 Apache가 2일 이상 실행될 때 발생합니다.
  • 스크립트의 프로파일링을 포함했습니다.여기서 입수하실 수 있습니다.
  • 이 전용 서버는 1개의 웹 사이트만 실행하기 위해 사용됩니다.이 사이트는 1분당 평균 1,000명의 방문자가 방문하는 높은 트래픽 사이트입니다.피크타임에는 1700~2000명의 관람객이 동시에 접속한다.

서버 사양

OS: Windows 2008 R2 64비트
CPU: 인텔 Core i5 - 4 코어
RAM: 8 GB
아파치 2.2
PHP 5.3.1
스토리지: 1 TB 하드 드라이브x 2
대역폭: 10 TB/월

솔루션

드디어 조정하여 문제를 해결했습니다.개선 작업을 여기서 소개합니다.

  1. favicon.ico내 루트 엔진을 망가뜨리는 게 없어비록 내 루트 엔진은 매우 작지만favicon.ico루트 엔진을 가동하지 않음으로써 메모리 사용량을 줄일 수 있습니다.제 웹사이트의 대부분에 그것이 있는데, 저는 그것을 이 새로운 섹션에 넣는 것을 잊었습니다.
  2. 제한.MaxRequestPerChild다른 전용 서버에서는,MaxRequestPerChild한정되어 있습니다.이 서버의 경우 0으로 설정합니다.나는 항상 각 대본이 고립되어 있다고 생각했다.스크립트를 실행하는 데 800kb가 걸린다고 칩시다.완료 후 Apache 또는 PHP는 800kb 메모리를 비워야 합니다.이런 식으로는 안 되는 것 같아요.제한적MaxRequestPerChild제한 후 새로운 프로세스를 생성하여 메모리 누수를 방지합니다.MaxRequestPerChild그리고 오래된 과정이 사라지고 있습니다.이게 저의 새로운 설정입니다.

    ThreadsPerChild      1500
    MaxRequestsPerChild  10000 
    
  3. ob_flush();메모리가 약간 줄어듭니다.별로 도움이 되진 않지만, 모든 최적화가 도움이 됩니다.

  4. 사용한 적이 있다xdebug이 질문에 대답하려는 사람들의 제안대로, 저는 한번도 사용해 본 적이 없습니다.이 툴은 뛰어난 툴이며, 몇 가지 작업을 최적화하여 조금 더 빠르게 실행할 수 있도록 했습니다.
  5. 불필요한 Apache 모듈을 몇 개 비활성화했습니다.1개씩 디세블로 하고, 다른 것을 디세블로 하기 전에, 완전하게 동작하는 것을 확인하기 위해서, 며칠간의 테스트를 실시하려고 하고 있습니다.불필요한 PHP 확장자는 모두 비활성화되어 있습니다.
  6. 이 서버의 스크립트는 대부분 기존 방식(템플릿 없음, 데이터베이스 계층 없음, 순수 PHP, HTML 및 레거시 mysql_* 함수)을 사용했습니다.솔직히 말해서, 그것은 매우 빨리 달리고 매우 작은 메모리를 사용했어요.그러나 웹사이트가 길어짐에 따라 스크립트의 유지보수가 쉽지 않습니다.저는 웹사이트의 일부를 적절한 프레임워크(저만의 작은 프레임워크)로 변환하려고 노력했습니다.크기가 작기 때문에 나만의 프레임워크를 사용한 이유(전체 프레임워크에 대해 3kb, 필요한 것만 포함)
  7. IIS7.5로 전환하면 이 문제가 완전히 해결됩니다.

스왑을 사용하려고 할 때 서버가 다운되는 것과 같은 문제가 발생했습니다.이는 mod_php가 메모리를 해방시키지 않기 때문입니다.따라서 Apache 프로세스는 Apache 또는 PHP의 메모리 제한에 도달하거나 제한이 없으면 서버를 중단시킵니다.

Apache를 재시작하면 새로운 슬림 프로세스를 생성할 수 있지만 PHP 스크립트를 실행함에 따라 문제가 발생할 때까지 계속 커집니다.

솔루션은 Apache를 생성하여 일정 수의 쿼리를 처리한 후 프로세스를 종료하는 것입니다.그러면 새로운 쿼리가 생성됩니다(관련 질문이 몇 가지 있습니다). MaxRequestsPerChild 구성 옵션을 예를 들어 100(기본값은 1000)으로 줄일 수 있습니다.

물론 새로운 프로세스를 종료하고 생성하는 데 리소스가 필요하기 때문에 서버 퍼포먼스가 저하될 수 있지만 적어도 사이트는 계속 작동합니다.높은 성능을 유지하기 위해 실행 중인 프로세스의 수를 늘리고 싶을 수 있습니다. PHP(또는 Apache) 메모리 제한 x 최대 프로세스 수가 서버의 물리적 RAM을 초과하지 않도록 하십시오.

제 경험입니다. 도움이 되길 바랍니다.

일단은memory_get_peak_usage()도움이 되지 않을 겁니다.에러의 원인이 된 메모리 용량과 같은 메모리 용량만 반환됩니다.

memory_get_usage는, 호출시에 할당되고 있는 액티브한 메모리의 양을 반환합니다.

ini_set('memory_limit', '256M');시스템 메모리의 PHP 풋프린트의 최대 허용량을 설정합니다.768K로 OOM이 표시되는 경우, 그것을 증가시켜도 문제는 해결되지 않습니다.

어떤 버전의 PHP를 사용하고 있는지 알 수 없지만, 즉시 업그레이드를 제안합니다.Zend의 메모리 매니저가 메모리 할당을 해제하지 못하는 버그가 몇 가지 있습니다.그 때문에, 같은 문제가 발생합니다.

로컬 서버와 프로덕션 서버 모두 동일한 버전의 OS, 동일한 롱비트 및 동일한 버전의 PHP를 실행하고 있습니까?대답은 '아니오'가 될 것이다.

창과 관련이 없는 경우malloc()이 문제는 서브 도메인이고 Virtual Host 내에 있으며 할당량이 768k에 불과하기 때문에 OS의 문제처럼 들릴 수 있습니다.

달려.tasklist명령 프롬프트를 표시합니다.프로세스 전체에서 Apache 스레드 또는 메모리 사용량이 증가하고 있습니까?

마지막으로 한 가지 더 생각하자면,flush()및/또는ob_flush();테이블 행/컬럼의 각 루프 뒤에 표시됩니다.이렇게 하면 버퍼가 클리어되고 문제가 발생할 경우 메모리가 절약됩니다.

우선 PHP를 5.4+로 업그레이드합니다.일부 어플리케이션에서는 최대 50% 고속입니다.메모리 누수 문제를 많이 해결했어요.becnhamrks를 참조하십시오.http://news.php.net/php.internals/57760

오류는 다음과 같습니다.Out of memory그리고 아니다Allowed memory size [..] exhausted.

메모리 누수는 시스템의 다른 곳에 있습니다.mysql 서버는 이 무거운 쿼리 후에 많은 시스템 메모리를 사용하고 apache/php를 물리적인 상태로 남겨두고 스왑할 수 있습니다.

이것에 의해, 에러는 항상 같은 행(및 같은 스크립트)에 표시됩니다.

xdebug를 설치하고 프로파일러 트리거를 활성화합니다.그래도 문제의 원인을 알 수 없는 경우 프로파일러 파일을 생성하고 캐시그린드파일을 게시합니다.

편집: 메모리 누수가 발생한 페이지의 프로파일러 파일입니다.

치명적인 오류:메모리 부족(할당 해결됨)
나도 비슷한 문제가 있었어, 몇 달 동안 해결책이 없었어.마지막으로 Apache 폴더 중 하나를 체크하고 있었습니다.즉, Apache의 메모리 할당을 제어하는 이 파일을 발견했습니다.파일명은 httpd-mpm 이며, MaxMemFree 는 2048 보다 높은 값으로 설정되어 있습니다.첫 번째 MaxMemFree (IfModule !mpm_netware_module) 에서는 10000으로 하고 두 번째 MaxMemFree 는 5000으로 설정했습니다.

이것으로 내 문제는 해결되었다.도움이 되었으면 좋겠다

내 생각엔 네가 편집하지 않았거나php.iniPHP 및/또는 웹 서버를 재시작하지 않은 경우.

작성하다phpinfo.php내용을 포함한 docroot 페이지<?php phpinfo();올바른 것을 변경했는지 확인합니다.php.ini. 의 장소와 더불어php.ini웹 서버가 사용하고 있는 파일, 또한 허용되는 최대 스크립트메모리를 나타냅니다.

다음으로 스택 트레이스를 몇 가지 페이지에 추가하여 이 원인이 된 일련의 이벤트를 확인할 수 있도록 하겠습니다.다음 함수는 치명적인 오류를 포착하고 발생한 일에 대한 자세한 정보를 제공합니다.

register_shutdown_function(function()
{
    if($error = error_get_last())
    {
        // Should actually log this instead of printing out...
        var_dump($error);
        var_dump(debug_backtrace());
    }
});

개인적으로 Nginx + PHP-FPM은 제가 느린 Apache를 떠난 이후 수년간 사용해 온 것입니다.

MySQL과 열려 있는 연결 수에 문제가 있을 수 있으므로 며칠마다 재시작하면 자동으로 정렬됩니다.스크립트 셧다운 시 자동으로 닫히나요?

이봐, 나도 내 서버에 같은 문제가 생겼어.다음 사항을 변경했을 뿐입니다.

바꾸다php.ini~에 대해서

memory_limit = 128M

추가하다httpd.conf

RLimitMEM 1073741824 2147483648

apache를 재기동하면, 다음의 에러가 삭제됩니다.

요약하자면 (이 답변은 원래 질문에서 상당히 멀리 떨어져 있습니다)

  • PHP는 적은 양의 메모리로 보이는 것을 할당할 수 없습니다.
  • 오류 발생 시 현재 메모리 사용량 + 요청된 양이 현재 적용 중인 메모리 제한보다 작음
  • 이 경우 시스템은 6Gb를 PHP에서 사용할 수 있습니다.
  • apache를 재기동하면 문제가 해결되기 때문에 apache로 인해 PHP에서 메모리를 사용할 수 없게 됩니다.

이 모든 것이 유효하다면 6Gb가 매우 단편화되어 있다는 것만이 가능한 설명입니다.그것은 조금 가능성이 낮다고 생각합니다.PHP가 Apache에서 어떻게 호출되는지 말하지 않았습니까? mod_php? fpm?Fcgi?

저는 위의 술어들, 특히 빈 메모리에 대해 각각 살펴보는 것으로 시작할 것입니다.에러가 발생했을 때, 6 Gb의 빈 용량이 있는 것을 어떻게 알 수 있습니까?보다 가능성이 높은 원인은 메모리 누설이 발생하고 있기 때문입니다.

Apache 구성 방법에 대한 자세한 내용은 제공하지 않았습니다.MaxRequestsPerChild와 MaxMemFree도 줄이고 싶습니다.(워크어 Apache가 스레드당 적용되는 곳은 잘 모르기 때문에 프로세스당 제한이 필요합니다.)Apache Configuration에서 핵심 설정을 제공해주면 추가 제안을 할 수 있을 것입니다.

Ajax를 광범위하게 사용하지 않는 한 킵얼라이브 시간이 2 이하인지 확인하십시오.

다음 2가지 사실은 메모리 누수를 분명히 나타내고 있습니다.

  1. 에러는 코드의 다른 행에 표시됩니다.
  2. 에러는, 메모리 할당이 비교적 적은 것을 보고한다.

먼저 PDO를 선택하여 다른 모든 확장 기능을 비활성화한 후 Sieve / Apache Bench (ab)와 같은 기능을 사용하여 하룻밤 사이에 실행되도록 합니다.또, 를 사용해 실행해 볼 수도 있습니다.cliinterface (메모리 제한을 동일하게 유지하도록 해 주세요).

스크립트 끝에 있는 함수를 사용하여 PHP가 얼마나 많은 메모리를 사용하고 있는지 확인할 수 있습니다.

고객님의 코멘트에 따르면 800kB로 괜찮습니다.메모리 부족의 원인이 되는 대용량의 메모리는 결코 아닙니다.-)

마지막으로, 현시점에서는 5.4로의 업그레이드는 권장하지 않지만, 5.3.1 이후 여러 가지 취약성과 누수로 인해 최신 5.3.x로의 업그레이드는 권장할 만한 가치가 있습니다.

며칠 전에 이런 일이 있었어요.신규 설치를 실시했는데도, 모두 보고 있는 한, 또 서버의 사양에 근거하고 있습니다.무한 루프라고 생각됩니다.PHP 코드 자체가 아니라 Apache에 대한 요청일 수 있습니다.

URL http://localhost/mysite/page_with_disples_disples에 접속했을 경우를 가정합니다.

여러 요청을 수신한 경우 Apache의 액세스 로그를 확인합니다.그 요청을 추적하여 시스템에 대한 '병목'을 일으킬 수 있는 코드(sendmail 사용 시 mine's exec()를 확인합니다.여기서 말하는 병목은 무한 루프일 필요는 없습니다.완료까지 시간이 걸리는 기능일 수 있습니다.또는 php의 '프로그램 실행 함수' 중 일부일 수 있습니다.

Ajax 요청(페이지 로드 시 실행되는 요청)도 확인해야 할 수 있습니다.Ajax 요구가 같은 URL로 리다이렉트 되는 경우

예: httpx://localhost/mysite/page_with_filen_filename

그것은 요구를 다시 처음부터 다시 '고정'시킬 것이다

임의의 행이나 스크립트가 끝나는 코드 자체를 투고하면 도움이 됩니다.어딘가에 '루프' 코드가 있을 수 있습니다.imho php는 무작위로 회선을 호출하지 않습니다.

http://blog.piratelufi.com/2012/08/browser-sending-multiple-requests-at-once/

이러한 에러가 발생하는 경우는, 대부분의 경우, 문제는 코드에 있습니다.나쁜 코드를 쓰고 있다는 것이 아니라, 이 정도의 메모리를 사용하고 있는 것을 주의 깊게 관찰할 필요가 있다는 것입니다.

항상 "PHP의 Garbage Collection은 매우 나쁘다"는 것을 기억하세요.Java나 다른 어떤 언어와도 다릅니다.gc_collect_cycle을 통해 가비지 수집을 강제하는 방법이 있지만, 제 개인적인 의견으로는 문제가 해결되지 않습니다.PHP는 요청과 응답 사이클이 완료되면 페이지 실행에 사용되는 모든 메모리를 해방합니다.따라서 백그라운드스크립트(Gearman 등)와 같이 장시간 실행 중인 경우 스크립트가 실행될 때까지 메모리가 해방되지 않기 때문에 메모리 문제가 발생할 수 있습니다.

위의 scr,pt가 해당되지 않는 경우, 그리고 당신이 말한 것처럼 대량의 메모리를 필요로 하는 코드가 없다면, 문제는 코드 자체에 있으며, PHP의 어떤 버전으로 업그레이드해도 문제가 해결되지 않습니다.Gearman 스크립트 중 하나를 사용한 적이 있는데, 하나의 변수를 어레이에 추가하는 루프에 문제가 있어 변수 자체가 매우 무거웠습니다(데이터 약 110KB).그러니까 코드를 꼼꼼히 살펴보는 게 좋을 것 같아요

래비쉬

PHP에서도 비슷한 문제가 있었습니다.

1) 에러 로그를 확인합니다.계속하기 전에 모든 오류를 제거하십시오.2) 사용되지 않는 모듈을 제거하기 위해 Apache 구성을 변경하는 것을 검토하십시오.이것에 대한 훌륭한 링크가 여기 있습니다.Wordpress에 특유하지만, 여전히 매우 유용합니다.http://thethemefoundry.com/blog/optimize-apache-wordpress/

내가 발견한 버그의 종류를 알기 위해, 나는 Facebook에 콘텐츠를 투고하려고 하는 코드를 가지고 있었고, Facebook은 그들의 API를 수정하여 이것이 고장났으며, 나는 또한 기본적으로 Facebook에 콘텐츠를 투고하려고 시도하고 많은 오브젝트를 메모리에 남겨두는 것을 의미했다.

프로파일러 출력 파일에서 마음에 들지 않거나 신뢰하지 않는 점이 몇 가지 발견되었습니다.이것들을 조사하겠습니다.

이상을 검출하기 위한 출력 번호의 의미나 PHP 스크립트가 어떻게 동작하는지를 모르는 것 이외에는 문제가 없습니까?같은 메인에 인크루드(include)가 있다.ph 파일, 재귀적인 것처럼 보이는 파일?

2121 fl=D:\www\football\views\main.php
2122 fn=include::D:\www\football\views\main.php

파일을 확인했습니다.D:\www\football\views\main.php는 몇 가지 문자열 함수를 여러 번 사용하고 있습니다.아마 쿼리에서 반환된 데이터에서 다음 함수를 호출하고 있을 것입니다.

strlen
substr
strtotime

C 언어에서와 같이 이러한 함수에 문자열이 필요한 경우null메모리 문제를 피하기 위해 terminated 또는 기타 문자열 끝의 terminator를 참조하십시오.

당신의 웹사이트 URL을 게시할 수 있습니까?

이는 Windows용 PHP v5.2에서 알려진 버그로 버전 5.2.3 이상에 존재합니다.https://bugs.php.net/bug.php?id=41615

제안된 수정이 전혀 도움이 되지 않아 PHP를 업데이트해야 합니다.

fcgid를 통해 php를 실행해 보십시오.이렇게 하면 도움이 될 수 있습니다.

PHP를 Apache 모듈로 실행할 때 나타나는 전형적인 오류입니다.우리는 몇 달 동안 이러한 오류와 씨름했습니다.mod_fcgid(James가 권장하는 대로)를 사용하여 PHP를 사용하면 이러한 모든 문제가 해결됩니다.최신 Visual C++ 재배포 가능 패키지가 설치되어 있는지 확인합니다.

http://support.microsoft.com/kb/2019667

또한 64비트 버전의 MySQL로 전환할 것을 권장합니다.32비트 버전을 실행할 실질적인 이유가 없습니다.

출처: php5ts.dll 5.5.1.0의 문제로 Apache 2.4.6.0이 크래시됨

서버의 물리/스왑 메모리가 부족하기 때문에 PHP는 충분한 메모리를 할당할 수 없습니다.

의 출력을 붙여넣을 수 있습니까?free여기?

제 경우, 이 오류는 방대한 선택 쿼리(수십만 개의 반환된 결과)로 인해 트리거되었습니다.

WordPress의 확장성을 테스트하기 위해 데이터베이스에 수백만 개의 레코드를 추가한 직후에 발생했기 때문에, 이것이 유일한 이유였습니다.

오래된 실타래인 건 알지만, 해결한 내 경험이 있어.

서버는 Apache를 실행하는 호스트 서비스입니다.

내 스크립트는 메모리 부족과 함께 6Mb에서 크래쉬했는데, 그때 내 제한은 256Mb - crazy, 맞죠?

클라이언트에서 실행 중인 javascript에서 http 콜백을 통해 동기 호출되어 약 550 콜 후에 크래시됩니다.무능한 지원자들과 많은 시간을 낭비한 후, 이제 내 대본은 마법처럼 흘러간다.

그들은 단지 php.ini를 리셋하는 것 뿐이었다고 말했지만, 나는 차이점을 확인했다.

메모리 부족 오류와 관련이 있을 수 있는 변경 사항은 없습니다.

웹 서버의 메모리 누수가 의심되는데, "Escalated Support" 담당자가 php.ini를 리셋하는 것처럼 위장하여 숨기고 있습니다.그리고 난 음모론자가 아니야

언급URL : https://stackoverflow.com/questions/12015569/fatal-error-out-of-memory-but-i-do-have-plenty-of-memory-php

반응형