PHP memory overflow solution

This article is reproduced from: http://www.cnblogs.com/zcy_soft/archive/2011/04/12/2013223.html Author: zcy_soft Please indicate the statement when reprinting.

one. memory overflow solution

When doing statistical analysis of data, large arrays are often encountered, and memory overflow may occur. Here I share my solution. Let's illustrate this problem with an example, as follows:

Assuming that the number of records stored in the log is 500,000 , the solution is as follows:

 

ini_set('memory_limit','64M'); // Reset the memory size that php can use to 64M . Generally, the php.ini file cannot be modified on the remote host , but can only be set by the program . Note: in safe_mode (safe mode), ini_set is invalid

set_time_limit(600);// Set the timeout limit to 6 minutes

$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); read the file into an array

array_shift($arr);//Move the first unit - > <?php exit;?>

$farr = array_merge($farr,$arr);

unset($arr);

}

}

if(empty($this->farr)){

echo ”<p><center>No related records!</center></p>”;

exit;

}

while(!empty($farr)){

$_sub = array_splice($farr, 0, 10000); //Remove 1000 in $farr each time

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);// Destroy when used up

}

unset($farr);

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

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

two. unset destroys variables and frees memory problem

PHP's unset() function is used to clear and destroy variables. We can use unset() to destroy unused variables. But sometimes, the memory occupied by variables cannot be destroyed with unset()! Let's look at an example first:

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

Finally, the memory occupied before unset() is output minus the memory occupied after unset(). If it is a positive number, it means that unset($s) has destroyed $s from memory (or in other words, the memory occupancy is reduced after unset()), But under the PHP5 and windows platform, the result I got is: 0. Does this mean that unset($s) does not destroy the memory occupied by the variable $s? Let's make the following example:

<?php
$s=str_repeat('1',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, that is, one more 1 than the first example, and 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 the memory space be released by using unset? Let's test it with another example:

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

Refreshing the page, we see that there are 256 1s in the first line and 0s in the second line. It stands to reason that we have destroyed $s, and $p only refers to the variable of $s, which should have no content. In addition, unset($ s) The memory usage has not changed before and after! Now let's do the following example:

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

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

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

We will use unset() to destroy both $s and $p. At this time, the difference in memory usage is also 272, indicating that this can also release memory. Then, we can get another conclusion:
conclusion two, only when all variables (such as reference variables) pointing to the variable are destroyed, the memory will be released.



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324222867&siteId=291194637