Home  >  Article  >  Backend Development  >  The most complete solution to PHP memory overflow

The most complete solution to PHP memory overflow

PHP中文网
PHP中文网Original
2016-07-25 08:58:523062browse

1. Memory overflow solution
When doing statistical analysis of data, we often encounter large arrays, and memory overflow may occur. Here I will share my solution. Let’s use an example to illustrate this problem, as follows:
Assume that the number of records stored in the log is 500,000, then the solution is as follows:

Copy the code The code is as follows:

ini_set(‘memory_limit','64M'); //重置php可以使用的内存大小为64M,一般在远程主机上是不能修改php.ini文件的,只能通过程序设置。注:在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);

Here, it is not difficult to see that on the one hand, we need to add The available memory size of PHP. On the other hand, as long as we find a way to process the array in batches, divide and conquer, and destroy (unset) the used variables in time, there will generally be no overflow problem.

In addition, in order to save PHP program memory consumption, we should reduce the use of static variables as much as possible. When data reuse is needed, you can consider using references (&). Another point is: after the database operation is completed, the connection must be closed immediately; after an object is used, the destructor (__destruct()) must be called promptly.

II. The problem of unset destroying variables and releasing memory
PHP’s unset() function is used to clear and destroy variables. We can use unset() to destroy unused variables. But sometimes, using unset() cannot destroy the memory occupied by the variable! Let’s look at an example first:

Copy the code as follows:

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

Finally output the memory occupied before unset() minus the memory occupied after unset(). If it is a positive number, it means that unset($s) has changed $s from Destroyed in memory (or in other words, the memory usage is reduced after unset()), but under PHP5 and Windows platforms, the result I got is: 0. Does this mean that unset($s) does not destroy the memory occupied by variable $s? Let’s make the following example again:

Copy the code as follows:

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

This example is almost the same as the above example. The only difference is that $s consists of 256 1s, which is one more than the first example. 1. The result is: 272. Does this mean that unset($s) has destroyed the memory occupied by $s?
Through the above two examples, we can draw the following conclusions:
Conclusion 1. The unset() function can only release the memory space when the variable value occupies more than 256 bytes of memory space.
So as long as the variable value exceeds 256, can using unset free up memory space? Let’s test it through another example:

Copy the code The code is as follows:

<?php
$s=str_repeat(&#39;1&#39;,256); //这和第二个例子完全相同
$p=&$s;
$m=memory_get_usage();
unset($s); //销毁$s
$mm=memory_get_usage();
echo $p.&#39;<br />&#39;;
echo $m-$mm;
?>

Refresh the page, we see that the first line has 256 1s, the second line is 0, it stands to reason that we have destroyed $s, and $p only refers to the variable of $s and should have no content. In addition, the memory usage does not change before and after unset($s)! Now let’s do the following example:

Copy the code as follows:

<?php
$s=str_repeat(&#39;1&#39;,256); //这和第二个例子完全相同
$p=&$s;
$m=memory_get_usage();
$s=null; //设置$s为null
$mm=memory_get_usage();
echo $p.&#39;<br />&#39;;
echo $m-$mm;
?>

Now refresh the page, we see that the output $p has no content, and the difference in memory usage before and after unset() is 272, that is, it has been Cleared the memory occupied by variables. $s=null in this example can also be replaced by unset(), as follows:

Copy the code as follows:

<?php
$s=str_repeat(&#39;1&#39;,256); //这和第二个例子完全相同
$p=&$s;
$m=memory_get_usage();
unset($s); //销毁$s
unset($p);
$mm=memory_get_usage();
echo $p.&#39;<br />&#39;;
echo $m-$mm;
?>

We will destroy both $s and $p using unset(), and then look at the memory usage The difference is also 272, indicating that this can also free up memory. Then, we can get another conclusion:
Conclusion 2. The memory will be released only when all variables (such as reference variables) pointing to the variable are destroyed.

The above is the most complete solution to PHP memory overflow. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn