치명적인 오류 : 메모리가 부족하지만 메모리가 충분합니다 (PHP).
내 질문이 점점 길어지고 있기 때문에 전체 질문을 다시 작성하여 더 좋고 짧게 만들기로 결정했습니다.
8GB 메모리가있는 전용 서버에서 웹 사이트를 운영합니다. php.ini 설정에서 메모리 제한을 높여야한다는 것을 잘 알고 있습니다. 128M에서 256M 및 -1로 설정했습니다. 여전히 문제는 끈기입니다.
치명적인 오류 : 81 행의 D : \ www \ football \ views \ main.php의 메모리 부족 (786432 할당 됨) (24576 바이트 할당 시도)
메모리 부족은 786432 바이트 만 할당되고 24576 바이트가 더 필요하다고 말했기 때문에 의미가 없습니다.
786432 바이트는 768KB에 불과하며 상당히 작습니다.
힌트
- 이 오류는 매우 임의의 줄에서 발생합니다. 81 번 줄에 항상 오류가있는 것은 아닙니다.
- 피크 시간에 Apache는 약 500MB의 메모리 만 사용합니다. 아직 6GB가 남아 있습니다.
- 무한 루프가 없습니다.
- 스크립트는 1,042,424 바이트를 사용합니다. 이 번호 가져 오기
echo memory_get_peak_usage();
- MySQL의 결과 집합은 작습니다 (최대 12 개의 행, 순수하게 텍스트, blob 데이터 없음).
- ( 중요 ) 이틀에 한 번씩 Apache를 다시 시작하면 오류가 사라집니다. 일반적으로 Apache가 2 일 이상 실행될 때 발생합니다.
- 스크립트 프로파일 링을 포함했으며 여기에서 얻을 수 있습니다 .
- 이 전용 서버는 순전히 하나의 웹 사이트 만 실행하는 데 사용됩니다. 이 웹 사이트는 매분 평균 1,000 명의 방문자가 방문하는 트래픽이 많은 웹 사이트입니다. 피크 타임에는 1,700 ~ 2,000 명의 방문자가 동시에 액세스합니다.
서버 사양
OS : Windows 2008 R2 64 비트
CPU : Intel Core i5-4 코어
RAM : 8GB
Apache 2.2
PHP 5.3.1
스토리지 : 2 x 1TB 하드 드라이브
대역폭 : 매월 10TB
해결책
마침내 문제를 조정하고 수정했으며 개선을 위해 수행 한 작업을 여기에서 공유하고 싶습니다.
favicon.ico
내 경로 엔진을 엉망으로 만드는 누락되었습니다. 내 경로 엔진은 매우 작지만를 포함favicon.ico
하면 경로 엔진을 실행하지 않아 메모리 사용량을 줄이는 데 도움이됩니다. 내 웹 사이트의 대부분에는이 기능이 있으며이 새 섹션에 넣는 것을 잊었습니다.한계가
MaxRequestPerChild
도움이됩니다. 다른 전용 서버에는MaxRequestPerChild
제한이 있습니다. 이 서버의 경우 0으로 설정했습니다. 저는 항상 각 스크립트가 격리되어 있다고 생각했습니다. 내 스크립트를 실행하는 데 800kb가 걸린다고 가정 해 보겠습니다. 완료되면 Apache 또는 PHP는 800kb 메모리를 확보해야합니다. 이런 식으로 작동하지 않는 것 같습니다. LimitedMaxRequestPerChild
는 제한된 후 새 프로세스를 만들고MaxRequestPerChild
이전 프로세스가 죽어가는 방식으로 메모리 누수를 방지하는 데 도움이됩니다 . 이것은 나의 새로운 설정입니다.ThreadsPerChild 1500 MaxRequestsPerChild 10000
ob_flush();
약간 더 많은 메모리를 줄입니다. 별로 도움이되지는 않지만 모든 최적화가 도움이됩니다.- 나는
xdebug
이 질문에 대답하려는 사람들이 제안한 것처럼 전에 사용하지 않은 것을 사용했습니다. 나는 그것이 훌륭한 도구라고 말해야하고 약간 더 빠르게 실행되도록 몇 가지 항목을 최적화했습니다. - 불필요한 Apache 모듈을 비활성화했습니다. 나는 그것을 하나씩 비활성화하려고 노력하고 있으며 다른 것을 비활성화하기 전에 완벽하게 작동하는지 며칠 테스트하십시오. 이제 불필요한 PHP 확장을 모두 비활성화했습니다.
- 이 서버에있는 대부분의 스크립트는 기존 방식을 사용했습니다 (템플릿 없음, 데이터베이스 레이어 없음, 순수 PHP, HTML 및 레거시 mysql_ * 함수). 솔직히 말하면 매우 빠르게 실행되고 매우 작은 메모리를 사용합니다. 그러나 웹 사이트가 길어짐에 따라 스크립트를 유지 관리하는 것은 그리 쉽지 않습니다. 나는 웹 사이트의 일부를 적절한 프레임 워크 (내 자신의 작은 프레임 워크)로 변환하려고했습니다. 저만의 프레임 워크를 사용한 이유는 그것이 작기 때문입니다 (전체 프레임 워크에 대해 3kb이고 필요한 것만 포함).
- IIS7.5로 전환하면이 문제를 완전히 해결할 수 있습니다 .
나는 스왑을 사용하려고 할 때 죽어가는 서버와 같은 종류의 문제를 겪었습니다. 이것은 mod_php가 메모리를 해제하지 않기 때문 입니다 . 따라서 Apache 프로세스는 아파치 또는 PHP의 메모리 제한에 도달하거나 제한이 없으면 서버가 중단됩니다.
아파치를 다시 시작하면 새로운 슬림 프로세스가 생성되지만 시간이 지남에 따라 PHP 스크립트를 실행하면 문제가 발생할 때까지 성장합니다.
해결책은 특정 수의 쿼리가 제공된 후 프로세스를 죽 이도록 아파치를 만드는 것입니다. 그러면 새 쿼리가 생성됩니다 ( 관련 질문 이 있습니다 ). MaxRequestsPerChild 구성 옵션을 100 (기본값 : 1000)으로 줄입니다.
물론 이것은 새로운 프로세스를 죽이고 생성하는 데 자원이 필요하기 때문에 서버 성능을 저하시킬 수 있지만 적어도 사이트는 계속 작동합니다. 높은 성능을 유지하기 위해 실행중인 프로세스의 수를 늘리고 싶을 수 있습니다. PHP (또는 아파치) 메모리 제한 x 최대 프로세스 수가 서버의 물리적 RAM을 넘지 않도록하십시오.
여기 내 경험이 있습니다. 도움이되기를 바랍니다.
우선 memory_get_peak_usage()
여기에서는 도움이되지 않습니다. 할당 된 메모리의 양만 반환하며 오류를 일으킨 숫자와 동일합니다.
memory_get_usage
호출 될 때 할당되는 활성 메모리 양을 반환합니다.
ini_set('memory_limit', '256M');
시스템 메모리에서 PHP의 풋 프린트의 최대 허용치를 설정합니다. 768K에서 OOM을 얻는 경우 업업해도 문제가 해결되지 않습니다.
사용중인 PHP 버전에 대한 표시는 없지만 즉시 업그레이드를 제안합니다. Zend의 메모리 관리자가 메모리 할당 해제에 실패하는 몇 가지 버그가있어 정확히 동일한 문제가 발생합니다.
로컬 서버와 프로덕션 서버가 모두 동일한 버전의 OS, 동일한 긴 비트 및 동일한 버전의 PHP를 실행하고 있습니까? 대답은 아니오입니다.
Windows malloc()
문제 와 관련이없는 경우 하위 도메인이고 아마도 VirtualHost 내에 있고 768k 만 할당하면 거의 OS 문제처럼 들립니다.
tasklist
스크립트에 액세스 할 때 명령 프롬프트에서 실행하십시오 . 추가 Apache 스레드 또는 프로세스 전체의 메모리 사용량이 급증합니까?
마지막 아이디어는 테이블 행 / 열에 대해 각 루프를 실행 flush()
하거나 실행하는 것입니다 ob_flush();
. 이렇게하면 버퍼가 지워지고 문제가 발생하는 경우에 대비하여 메모리를 절약 할 수 있습니다.
일부 응용 프로그램의 경우 최대 50 % 더 빠르기 때문에 PHP를 5.4+로 업그레이드하는 것으로 시작합니다. 그들은 많은 메모리 누수를 수정했습니다. becnhamrks를 참조하십시오 : http://news.php.net/php.internals/57760
오류는 Out of memory
이고 아닙니다 Allowed memory size [..] exhausted
.
따라서 메모리 누수는 시스템의 다른 곳에 있습니다. 이 무거운 쿼리 후에 mysql 서버가 많은 시스템 메모리를 사용하여 apache / php가 물리적 및 스왑없이 남겨질 수 있습니다.
이것은 항상 같은 줄 (및 / 또는 같은 스크립트)에 오류를 설명해야합니다.
xdebug를 설치하고 프로파일 러 트리거를 활성화합니다. 프로파일 러 파일을 생성 한 다음 여전히 문제의 원인을 알 수없는 경우 cachegrind 파일을 게시하십시오.
편집 : 물론 메모리 누수가 발생하는 페이지의 프로파일 러 파일!
나는 php.ini
당신이 권리를 편집하지 않았 거나 PHP 및 / 또는 웹 서버를 다시 시작하지 않았을 것입니다.
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은 내가 느린 아파치를 떠난 이후로 몇 년 동안 사용해온 것입니다.
MySQL 및 열린 연결 수에 문제가 될 수 있으므로 며칠마다 다시 시작할 때 자동으로 정렬됩니다. 스크립트 종료시 자동으로 닫히나요?
이봐 나도 내 서버에서 같은 문제가 발생했습니다. 다음 사항을 변경했습니다.
변경 php.ini
...
memory_limit = 128M
그리고 추가 httpd.conf
RLimitMEM 1073741824 2147483648
아파치를 다시 시작하고 오류를 제거했습니다.
요약하자면 (원래 질문과 상당히 거리가 먼이 답변을 추가하고 있습니다) :
- PHP는 적은 양의 메모리로 보이는 것을 할당 할 수 없습니다.
- 오류 occrs + 요청 된 양이 현재 시행중인 메모리 제한보다 적을 때의 현재 메모리 사용량
- 이 경우 시스템에는 PHP에서 사용할 수있는 6Gb가 있습니다.
- since the problem is resolved by restarting apache - it's apache which is preventing the memory from beig available to PHP
If these are all valid then the only possible explanation is that the 6Gb is very fragmented - which I think is a little unlikely. You didn't say how PHP is invoked from Apache - mod_php? fpm? Fcgi?
I would start by examining each of the above predicates - particularly the free memory one. How do you know that there's 6Gb free when the error occurs? A more likely cause is that there's a memory leak occurring which you're not spotting.
You've not provided any details of how apache is configured; I'd also have a look at reducing MaxRequestsPerChild and MaxMemFree. (I'm not very familiar with worker apache where this will apply per thread - really you need a limit per process). If you provided the core setting from the apache config then maybe we could make further suggestions.
Unless you are using Ajax extensively, make sure your keepalive time is 2 or less.
Fatal error: Out of memory (allocated SOLVED
i had similar problem, for months no solution. finally i was checking in one of the apache folders i.e(\apache\conf\extra) i came across this file that controls the memory allocation of apache. the file name is httpd-mpm in that file you are to increase the MaxMemFree which is set 2048 to something higher, i took mine to 10000 for the first MaxMemFree (IfModule !mpm_netware_module) then made the second one MaxMemFree to 5000 IfModule mpm_netware_module.
These solved my problem. hope it helps
The following two facts definitely point to memory leaks:
- The error appears at different lines in your code,
- The error reports a relatively small memory allocation.
I would first single out PDO, disabling all the other extensions and let it run overnight using something like Siege / Apache Bench (ab). You could also try running it using the cli
interface (just make sure you keep the same memory limits).
You could use the memory_get_peak_usage()
function at the end of your script to see how much memory PHP thinks it has been using.
From your comment that's 800 kB, which is okay; definitely not the gigantic amount of memory that would cause an out-of-memory ;-)
Lastly, though I wouldn't recommend upgrading to 5.4 at this point, upgrading to the latest 5.3.x is probably worth it due to multiple vulnerabilities and leaks that have been addressed since 5.3.1
this happened to me a few days ago. I did a fresh installation and it still happened. as far as everyone sees and based on your server specs. most likely it is an infinite loop. it could be not on the PHP code itself but on the requests made to Apache.
lets say when you access this url http://localhost/mysite/page_with_multiple_requests
Check your Apache's access log if it receives multiple requests. trace that request and check out the code that might cause a 'bottleneck' to the system (mine's exec() when using sendmail). The bottleneck im talking about doesn't need to be an 'infinite loop'. It could be a function that takes sometime to finish. or maybe some of php's 'program execution functions'
You might need to check ajax requests too (the ones that execute when the page loads). if that ajax request redirects to the same url
e.g. httpx://localhost/mysite/page_with_multiple_requests
it would 'redo' the requests all over again
it would help if you post the random lines or the code itself where the script ends maybe there is a 'loop' code somewhere there. imho php won't just call random lines for nothing.
http://blog.piratelufi.com/2012/08/browser-sending-multiple-requests-at-once/
Most of the time you get such a error, problem is in code. I am not trying to say that you are writing code that is bad, I am trying to say that you need to carefully observe what's there in that is using this much amount of memory.
Always remember "Garbage collection in PHP is pretty bad", it's not like Java, any other such language. there is a way to enforce garbage collection through gc_collect_cycle, but, in my personal opinion, that won't solve your problem. PHP free all memory used for executing a page, once request-response cycle is complete, so you may run into memory issues, if your script is long running, like a background script(Gearman etc), because, memory isn't freed till script is running.
If above is not the case with your scr,pt, and as you said there is no code that requires such a huge amount of memory, then problem is most definitely in code it self, and upgrading to any version of PHP won't solve the problem. I was facing with one of my Gearman scripts once, and there was a problem with one of my loop where I was appending one variable to one of my array, the variable itself was very heavy (approx 110KB of data). So I would suggest, do a careful inspection of your code.
Ravish
I had a similar problem with PHP:
1) Check your error logs. Eliminate EVERY error before continuing. 2) Consider modifying your apache configuration to eliminate unused modules - this will reduce the footprint needed by PHP - here's a great link for this - it's specific to Wordpress but should still be very useful http://thethemefoundry.com/blog/optimize-apache-wordpress/
To give you an idea of the kind of bug I found, I had some code that was trying to post content to Facebook, Facebook then modified their API so this broke, I also used a 'content expirator' which basically meant that it kept retrying to post this content to Facebook and leaving loads of objects lying in memory.
From the profiler output file I've noticed a couple of things which I did not like/trust much and would look into these:
Apart from not knowing the meaning of the output numbers to detect an anomaly or how PHP scripts work..., Is this not a problem? Having an include to the same main.ph file, which looks like a recursive thing?
2121 fl=D:\www\football\views\main.php
2122 fn=include::D:\www\football\views\main.php
Noticed the file D:\www\football\views\main.php
is making use of some string functions several times, I guess it is calling these functions on the data returned by your query:
strlen
substr
strtotime
If, like in the C language, these functions require strings be null
terminated or some other end of string terminator to avoid memory problems, I would look at the strings returned by your query.
Can you post the url of your website?
This is a known bug in PHP v 5.2 for Windows, it is present at least to version 5.2.3: https://bugs.php.net/bug.php?id=41615
None of the suggested fixes have helped for us, we're going to have to update PHP.
Try to run php over fcgid, this may help:
These are the classic errors you will see when running PHP as an Apache module. We struggled with these errors for months. Switching to using PHP via mod_fcgid (as James recommends) will fix all of these problems. Be sure you have the latest Visual C++ Redistributable package installed:
http://support.microsoft.com/kb/2019667
Also, I recommend switching to the 64-bit version of MySQL. No real reason to run the 32-bit version anymore.
Source: Apache 2.4.6.0 crash due to a problem in php5ts.dll 5.5.1.0
I would say the server is running out of physical/swap memory, so PHP can't allocate enough memory.
Can you paste the output of free
here?
For my case, this error was triggered because of a huge select query (hundreds of thousands of returned results).
It arose immediately after adding millions of records in my Database to test the scalability of WordPress, so it was the only probable reason for me.
'code' 카테고리의 다른 글
.less 파일에서 Visual Studio 2010 .css Intellisense를 켜는 방법 (0) | 2020.12.05 |
---|---|
Chrome은 Safari 및 Firefox와 다르게 색상을 렌더링합니다. (0) | 2020.12.05 |
람다 식을 대리자 또는 식 트리 형식으로 먼저 캐스팅하지 않고 동적으로 전달 된 작업에 대한 인수로 사용할 수 없습니다. (0) | 2020.12.05 |
@SpringApplicationConfiguration, @WebIntegration이 Spring Boot Framework에서 더 이상 사용되지 않기 때문에 적절한 주석은 무엇입니까? (0) | 2020.12.05 |
Kotlin : 클래스에서 객체와 컴패니언 객체의 차이점 (0) | 2020.12.05 |