A solution to the PHP memory overflow problem

  • 2020-06-19 09:59:59
  • OfStack

1. Memory overflow solution
When doing statistical analysis of data, large arrays are often encountered, which may cause memory overflow. Here I share 1 of my solutions. Here are some examples to illustrate the point:
Assuming that there are 500,000 records in the log, the solution is as follows:

 
ini_set( ' memory_limit','64M'); // reset php The available memory size is 64M . 1 Generally cannot be modified on remote host php.ini File, can only be set through the program. Note: in safe_mode In safe mode, ini_set failure 
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);// Remove the first 1 Unit - - <?php exit;?>
$farr = array_merge($farr,$arr);
unset($arr);
}
}
if(empty($this->farr)){
echo  " <p><center> No record! </center></p> " ;
exit;
}
while(!empty($farr)){
$_sub = array_splice($farr, 0, 10000); // Every time out $farr In the 1000 a 
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 them when they are used up 
}
unset($farr);

In this case, it is not hard to see that, on the one hand, we need to increase the available memory size of PHP, and on the other hand, as long as we find a way to batch the array, divide and conquer, and destroy the used variables in time (unset), there will be no overflow problem.

In addition, to save memory on the PHP program, we should minimize the use of static variables and consider using references ( & ). Another point is: the database operation is completed, to close the connection immediately; Call the destructor (___ 12en ()) after each object has been used.

2. unset destroys variables and releases memory issues
The unset() function of PHP is used to remove and destroy variables. For variables that are not used, we can use unset() to destroy them. In some cases, however, unset() does not destroy variable memory! Let's start with an example:


<?php
$s=str_repeat('1',255); // Produced by the 255 a 1 Composed string 
$m=memory_get_usage(); // Gets the currently occupied memory 
unset($s);
$mm=memory_get_usage(); //unset() Then look at the current memory footprint 
echo $m-$mm;
?>

If the number is positive, then unset($s) has destroyed $s from the memory (or reduced the memory footprint after unset()). However, on the PHP5 and windows platforms, I get 0. Does this mean that unset($s) does not destroy the memory used by the variable $s? Let's do the following example:

<?php
$s=str_repeat('1',256); // Produced by the 256 a 1 Composed string 
$m=memory_get_usage(); // Gets the currently occupied memory 
unset($s);
$mm=memory_get_usage(); //unset() Then look at the current memory footprint 
echo $m-$mm;
?>

This example is almost identical to the one above, except that $s consists of 256 ones, or 1 more ones than the first example, giving the result: 272. Does this indicate that unset($s) has destroyed the memory used by $s?
From the above two examples, we can draw the following conclusions:
The unset() function will only free up memory if the variable value occupies more than 256 bytes of memory.
Does unset free up memory as long as the variable value exceeds 256? Let's test 1 with another example:

<?php
$s=str_repeat('1',256); // This and the first 2 The examples are exactly the same 
$p=&$s;
$m=memory_get_usage();
unset($s); // The destruction $s
$mm=memory_get_usage();
echo $p.'<br />';
echo $m-$mm;
?>

Refresh the page, we see that there are 256 ones in line 1 and 0 in line 2. Supposedly, we have destroyed $s, while $p only refers to the variable of $s, so there should be no content. Besides, unset($s) has no change in memory usage before and after! Now let's do the following example:

<?php
$s=str_repeat('1',256); // This and the first 2 The examples are exactly the same 
$p=&$s;
$m=memory_get_usage();
$s=null; // Set up the $s for null
$mm=memory_get_usage();
echo $p.'<br />';
echo $m-$mm;
?>

Now refresh the page and we see that the output of $p is empty. 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); // This and the first 2 The examples are exactly the same 
$p=&$s;
$m=memory_get_usage();
unset($s); // The destruction $s
unset($p);
$mm=memory_get_usage();
echo $p.'<br />';
echo $m-$mm;
?>

We use unset() to destroy both $s and $p, and the difference of memory usage is 272, indicating that this can also free the memory. Then, we can come to another conclusion:
Conclusion 2. Memory is not freed until all variables pointing to the variable, such as reference variables, have been destroyed.


Related articles: