>  기사  >  백엔드 개발  >  PHP 메모리 오버플로 문제를 해결하는 방법은 무엇입니까?

PHP 메모리 오버플로 문제를 해결하는 방법은 무엇입니까?

coldplay.xixi
coldplay.xixi원래의
2020-07-01 16:27:454887검색

PHP 메모리 오버플로 문제를 해결하는 방법: 1. PHP의 사용 가능한 메모리 크기를 늘립니다. 2. 배열을 일괄 처리하고 사용된 변수를 시간 내에 삭제합니다. 3. 정적 변수의 사용을 최대한 줄입니다. . 데이터베이스 작업이 완료되면 즉시 연결을 닫습니다.

PHP 메모리 오버플로 문제를 해결하는 방법은 무엇입니까?

PHP 메모리 오버플로 문제를 해결하는 방법:

1. 메모리 오버플로 솔루션

데이터를 통계적으로 분석하다 보면 대규모 배열을 자주 접하게 되고, 메모리 오버플로가 발생할 수 있습니다. 여기서 해결 방법을 공유하겠습니다. 이 문제를 설명하기 위해 다음과 같은 예를 사용하겠습니다.

로그에 저장된 레코드 수가 500,000개라고 가정하면 해결 방법은 다음과 같습니다.

ini_set(‘memory_limit’,’64M’); 

//PHP에서 사용할 수 있는 메모리 크기를 다음으로 재설정합니다. 64M, 일반적으로 원격 호스트에 있음 php.ini 파일은 수정할 수 없으며 프로그램을 통해서만 설정할 수 있습니다.

참고: safe_mode(안전 모드)에서는 ini_set가 유효하지 않습니다. safe_mode(安全模式)下,ini_set失效。

set_time_limit(600);//设置超时限制为6分钟
$farr = $Uarr = $Marr = $IParr = $data = $_sub = array();
$spt = ”$@#!$”;
$root = ”/Data/webapps/VisitLog”;
$path = $dpath = $fpath = NULL;
$path = $root.”/”.date(“Y-m”,$timestamp);
$dpath = $path.”/”.date(“m-d”,$timestamp);
for($j=0;$j<24;$j++){
$v = ($j < 10) ? ”0″.$j : $j;
$gpath = $dpath.”/”.$v.”.php”;
if(!file_exists($gpath)){
continue;
} else {
$arr = file($gpath);////将文件读入数组中
array_shift($arr);//移出第一个单元-》<?php exit;?>
$farr = array_merge($farr,$arr);
unset($arr);
}
}
if(empty($this->farr)){
echo ”<p><center>没有相关记录!</center></p>”;
exit;
}
while(!empty($farr)){
$_sub = array_splice($farr, 0, 10000); //每次取出$farr中1000个
for($i=0,$scount=count($_sub);$i<$scount;$i++){
$arr = explode($spt,$_sub[$i]);
$Uarr[] = $arr[1]; //vurl
$Marr[] = $arr[2]; //vmark
$IParr[] = $arr[3].” |$nbsp;”.$arr[1]; //IP
}
unset($_sub);//用完及时销毁
}
unset($farr);

这里,不难看出:

1、一方面,我们要增加PHP可用内存大小,另一方面,只要我们想办法对数组进行分批处理,分而治之,将用过的变量及时销毁(unset),一般是不会出现溢出问题的。

2、另外,为了节省PHP程序内存损耗,我们应当尽可能减少静态变量的使用,在需要数据重用时,可以考虑使用引用(&)。

3、再一点就是:数据库操作完成后,要马上关闭连接;一个对象使用完,要及时调用析构函数(__destruct())。

二.unset销毁变量并释放内存问题

PHP的unset()函数用来清除、销毁变量,不用的变量,我们可以用unset()将它销毁。但是某些时候,用unset()却无法达到销毁变 量占用的内存!我们先看一个例子:

<?php
$s=str_repeat(&#39;1&#39;,255); //产生由255个1组成的字符串
$m=memory_get_usage(); //获取当前占用内存
unset($s);
$mm=memory_get_usage(); //unset()后再查看当前占用内存
echo $m-$mm;
?>

最后输出unset()之前占用内存减去unset()之后占用内存,如果是正数,那么说明unset($s)已经将$s从内存中销毁(或者说,unset()之后内存占用减少了),可是我在PHP5和windows平台下,得到的结果是:0。这是否可以说明,unset($s)并没有起 到销毁变量$s所占用内存的作用呢?我们再作下面的例子:

<?php
$s=str_repeat(&#39;1&#39;,256); //产生由256个1组成的字符串
$m=memory_get_usage(); //获取当前占用内存
unset($s);
$mm=memory_get_usage(); //unset()后再查看当前占用内存
echo $m-$mm;
?>

这个例子,和上面的例子几乎相同,唯一的不同是,$s由256个1组成,即比第一个例子多了一个1,得到结果是:272。这是否可以说 明,unset($s)已经将$s所占用的内存销毁了?

通过上面例子,我们可以得出以下结论:

结论一、unset()rrreee

여기서는 어렵지 않습니다.

1. 한편으로는 배열을 일괄 처리하는 방법을 찾는 한 PHP의 사용 가능한 메모리 크기를 늘려야 합니다. , 사용된 변수를 제때에 분할 및 정복하고 파기(unset)하면 일반적으로 오버플로 문제가 발생하지 않습니다.

2. 또한, PHP 프로그램 메모리 소모를 줄이기 위해서는 정적 변수의 사용을 최대한 줄여야 하며, 데이터를 재사용해야 하는 경우 참조(&) 사용을 고려할 수 있습니다. 3. 또 다른 점은 데이터베이스 작업이 완료된 후 개체를 사용한 후 즉시 연결을 닫아야 하며 소멸자(__destruct())를 즉시 호출해야 한다는 것입니다.

🎜II. unset이 변수를 삭제하고 메모리를 해제하는 문제 🎜🎜🎜PHP의 unset() 함수는 변수를 삭제하고 삭제하는 데 사용됩니다. unset()을 사용하여 사용되지 않는 변수를 삭제할 수 있습니다. . 그러나 때때로 unset()을 사용해도 변수가 차지하는 메모리를 파괴할 수 없는 경우가 있습니다! 먼저 예를 살펴보겠습니다. 🎜rrreee🎜최종 출력 unset() 이전에 차지한 메모리에서 unset() 이후에 차지한 메모리를 뺀 값입니다. 이는 unset ($s)가 메모리에서 $s를 파괴했음을 의미합니다(즉, unset() 이후 메모리 사용량이 감소했음). 그러나 PHP5 및 Windows 플랫폼에서는 결과가 I 얻은 값은 0입니다. 이는 unset($s)가 $s 변수가 차지하는 메모리를 파괴하지 않는다는 뜻인가요? 다음 예를 들어보겠습니다. 🎜rrreee🎜이 예는 위의 예와 거의 동일합니다. 유일한 차이점은 $s가 첫 번째 예보다 1이 더 많은 256개의 1로 구성된다는 점입니다. 결과는 272입니다. 이는 unset($s)$s가 차지하는 메모리를 파괴했다는 의미입니까? 🎜🎜위의 예를 통해 다음과 같은 결론을 내릴 수 있습니다. 🎜🎜결론 1. unset() 함수는 변수 값이 256바이트 이상의 메모리 공간을 차지하는 경우에만 메모리 공간을 해제할 수 있습니다. 🎜🎜결론 2. 해당 변수를 가리키는 모든 변수(예: 참조 변수)가 소멸되어야 메모리가 해제됩니다. 🎜🎜🎜관련 학습 권장 사항: 🎜초보부터 마스터까지 PHP 프로그래밍🎜🎜🎜

위 내용은 PHP 메모리 오버플로 문제를 해결하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.