A Memory Overflow Solution
When doing statistical analysis of data, often encounter large arrays, memory overflow may occur, here to share my solution. Use examples to illustrate the problem, as follows:
Assuming that the log holds 500,000 records, the solution is as follows:
Copy Code code as follows:
ini_set (' memory_limit ', ' 64M '); Reset PHP can use the memory size of 64M, generally on the remote host is not modify the php.ini file, only through program settings. Note: Under Safe_mode (Safe mode), Ini_set failure
Set_time_limit (600);/set timeout limit of 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 files into the array
Array_shift ($arr);/move out of the first unit-<?php exit;? >
$farr = Array_merge ($farr, $arr);
unset ($arr);
}
}
if (empty ($this->farr)) {
echo "<p><center> no relevant records! </center></p> ";
exit;
}
while (!empty ($farr)) {
$_sub = Array_splice ($farr, 0, 10000); 1000
each time you remove the $farr
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
in time
}
unset ($farr);
Here, it is not difficult to see, on the one hand, we want to increase the size of PHP available memory, on the other hand, as long as we think of ways to batch processing of the array, divide and conquer, will be used in time to destroy the variable (unset), generally will not overflow problems.
In addition, in order to save PHP program memory loss, we should minimize the use of static variables, when the need for data reuse, we can consider using the reference (&). One more thing: After the database operation completes, must close the connection immediately, after an object is used, must call the destructor (__destruct ()) in time.
Two Unset destroys variables and frees memory problems
the unset () function of PHP is used to erase and destroy variables, and we can destroy them with unset (). But at some point, unset () cannot achieve the memory consumed by the destruction variable! Let's take a look at an example:
Copy Code code as follows:
<?php
$s =str_repeat (' 1 ', 255); Produces a string consisting of 255 1
$m =memory_get_usage (); Gets the currently occupied memory
unset ($s);
$mm =memory_get_usage (); Unset () and then view the current memory footprint
Echo $m-$mm;
?>
After the final output unset () consumes memory minus unset () and if it is positive, then unset ($s) has destroyed $s from memory (or, after unset () the memory footprint is reduced), but I am under PHP5 and Windows platforms, The results are: 0. Does this indicate that unset ($s) does not play a role in destroying the memory occupied by the variable $s? Let us make the following example:
Copy Code code as follows:
<?php
$s =str_repeat (' 1 ', 256); Produces a string consisting of 256 1
$m =memory_get_usage (); Gets the currently occupied memory
unset ($s);
$mm =memory_get_usage (); Unset () and then view the current memory footprint
Echo $m-$mm;
?>
This example is almost the same as the example above, the only difference being that the $s is made up of 256 1, that is, a 1 more than the first example, and the result is: 272. Does this indicate that unset ($s) has destroyed the memory occupied by $s?
with the above two examples, we can draw the following conclusions:
Conclusion the unset () function frees up memory space only if the variable value occupies more than 256 bytes of memory space.
so as long as the value of the variable is more than 256, you can use unset to free up memory space? Let's test it again with an example:
Copy Code code as follows:
<?php
$s =str_repeat (' 1 ', 256); This is exactly the same as the second example
$p =& $s;
$m =memory_get_usage ();
unset ($s); Destruction of $s
$mm =memory_get_usage ();
echo $p. ' <br/> ';
Echo $m-$mm;
?>
Refresh the page, we see the first row has 256 1, the second line is 0, we have destroyed the $s, and $p just reference $s variables, there should be no content, in addition, unset ($s) before and after the memory footprint did not change! Now let's take the following example:
Copy Code code as follows:
<?php
$s =str_repeat (' 1 ', 256); This is exactly the same as the second example
$p =& $s;
$m =memory_get_usage ();
$s =null; Set $s to null
$mm =memory_get_usage ();
echo $p. ' <br/> ';
Echo $m-$mm;
?>
Now refresh the page, we see that the output $p has no content, unset () before and after the difference of memory footprint is 272, that is, the variable occupied memory has been cleared. The $s=null in this example can also be replaced by unset (), as follows:
Copy Code code as follows:
<?php
$s =str_repeat (' 1 ', 256); This is exactly the same as the second example
$p =& $s;
$m =memory_get_usage ();
unset ($s); Destruction of $s
unset ($p);
$mm =memory_get_usage ();
echo $p. ' <br/> ';
Echo $m-$mm;
?>
We use unset () to destroy both $s and $p, and then the difference between the memory footprint is also 272, which means that memory can also be freed. So, we can get another conclusion:
conclusion Two, the memory is freed only when all variables that point to the variable, such as reference variables, are destroyed.