Discuss Getting Memory Size Fatal Error in the PHP Development forum on Dev Shed. Getting Memory Size Fatal Error PHP Development forum discussing coding practices, tips on PHP, and other PHP-related topics. PHP is an open source scripting language that has taken the web development industry by storm.
Posts: 259
Time spent in forums: 4 Days 55 m 36 sec
Reputation Power: 0
Code Critique - Getting Memory Size Fatal Error
I executed my code and get this error:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 524288 bytes) in D:\website\root\aglam\viewTestResult2.php on line 172
Did and some googling and it is about my code. Tried to fix it but it still happen. My code using 2-D array. Attach is my code. Can someone provide the solution?
<div id="main">
<h2>Laboratory Result</h2>
<table border="1">
<tr>
<td>Period: <strong><?php echo showPeriodName(mysql_real_escape_string($_POST['period_id'])); ?></strong></td>
<td>Sample: <strong><?php echo showSampleName(mysql_real_escape_string($_POST['sample_id'])); ?></strong></td>
<td>Parameter: <strong><?php echo showParameterName(mysql_real_escape_string($_POST['param_id'])); ?></strong></td>
</tr>
</table>
<table border="0">
<tr>
<td valign="top">
<table border="1">
<tr>
<td colspan="2" align="center"><strong>Iteration</strong></td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td><strong>Laboratory</strong></td>
<td align="center"><strong>d1</strong></td>
</tr>
<?php showResultTable($_POST['period_id'], $_POST['sample_id'], $_POST['param_id']); ?>
</table>
</td>
<td valign="top">
<?php
echo "<table border='1'>";
$sqlShowLab = "SELECT a.lab_name, b.testing_result
FROM laboratory AS a JOIN enroll_testing AS b ON a.lab_id = b.lab_id
JOIN sample_period AS c ON b.sp_id = c.sp_id
WHERE c.period_id = ".$_POST['period_id']."
AND c.sample_id = ".$_POST['sample_id']."
AND b.parameter_id = ".$_POST['param_id']."
AND b.testing_result IS NOT NULL ORDER BY b.testing_result ASC";
$qryShowLab = mysql_query($sqlShowLab) or die ("Error: Unable to show Laboratory Name.");
$rowShowLab = mysql_num_rows($qryShowLab);
if($rowShowLab != 0)
{
$mainIndex = 0; // set main index/pointer. it should hold no of labs.
$internalIndex = 0; // set 2nd index/pointer. it should hold testing result for each lab and sample
while($rShowLab = mysql_fetch_assoc($qryShowLab))
{
//$arrLabName[$mainIndex][$internalIndex] = $rShowLab['lab_name'];
$arrTestResult[$mainIndex][$internalIndex] = $rShowLab['testing_result']; // hold testing result for each lab and sample
$internalIndex++;
}
$totalLabs = count($arrTestResult[$mainIndex]); // count total lab from multi-dimensional array above
$loop = true; // initial loop value
$loopCount = 0; // set loop count to 0. no of loop should match with $mainIndex value which is no of sample
$countMatch = 0; // set count match newX and newS
while($loop = true)
{
$i = 0; // count no of lab
$totalAvg = 0; // set total average value
while($i < $totalLabs)
{
// sum up testing result for each sample. loop count hold pointer val which point to a single sample_id
$totalAvg = $totalAvg + $arrTestResult[$loopCount][$i];
$i++;
}
// find average val of testing result of each sample_id. loop count hold pointer val which point to a single sample_id
$average[$loopCount] = number_format($totalAvg / count($arrTestResult[$loopCount]), 2);
// calc rob std deviation of each sample_id
$stdDeviation[$loopCount] = number_format(sd($arrTestResult[$loopCount]), 2);
if($loopCount == 0)
$newX[$loopCount] = findMedian($arrTestResult[$loopCount]); // find median val for the 1st loop of loop count
else
$newX[$loopCount] = number_format($totalAvg / $totalLabs, 2); //$newX[$loopCount]=$average[$loopCount];,find newX for the rest loop count
/* 2nd part of table & calc. find absolute values */
$x = 0; // count no of lab
while($x < $totalLabs)
{
if($loopCount == 0)
$val[$loopCount][$x] = abs($arrTestResult[$loopCount][$x] - $newX[$loopCount]);
else
$val[$loopCount][$x] = pow(abs($arrTestResult[$loopCount][$x] - $newX[$loopCount]), 2);
/* continue back to 1st part/table */
// + 1 is added just to move the value to next loop index
$delta[$loopCount] = number_format(1.5 * $newS[$loopCount], 2);
$arg1[$loopCount] = number_format($newX[$loopCount] - $delta[$loopCount], 2);
$arg2[$loopCount] = number_format($newX[$loopCount] + $delta[$loopCount], 2);
<!-- Please don't delete this. You can use this template for free and this is the only way that you can say thanks to me -->
<p id="dont-delete-this">Powered by <a href="#">KN TEAM</a> | Design Template by <a href="http://www.davidkohout.cz">David Kohout</a></p>
<!-- Thank you :) -->
</div>
</div>
</body>
</html>
Posts: 377
Time spent in forums: 1 Week 3 h 27 m 44 sec
Reputation Power: 293
the error is saying that the PHP memory limit is getting hit by your script. Change php.ini to increase the limit.
look for "memory_limit = 128M" and change it to a higher value . If it's not in the file, add it.
Better still, go though your code and try and optimise it. I didn't look too deeply into your code, but unless you are doing some hardcore data manipulation, or extracting a very large amount of data from the DB you shouldn't be using 128MB of ram.
Also, on a side note, you need to review some security issues with your code. Never EVER use unsanitised data in your db queries. Things like:
are very very bad. You are using user input data ($_POST) directly into a query. You are wide open to sql injection with that. Also, you should stop using mysql_connect() and look into PDO with prepared statements.
__________________
"Take thy beak from out my heart, and take thy form from off my door" - Homer J Simpson / Edgar Allan Poe
Posts: 259
Time spent in forums: 4 Days 55 m 36 sec
Reputation Power: 0
Quote:
Originally Posted by sir_drinxalot
the error is saying that the PHP memory limit is getting hit by your script. Change php.ini to increase the limit.
look for "memory_limit = 128M" and change it to a higher value . If it's not in the file, add it.
thanks for the suggestion but I still get the same error. I did change to memory_limit = 2048M but it still produces the same error. However, the error pointed to different line of code. This time at line 107.
thanks again on your recommendation regarding my code. Will fix it immediately Currently conducting unit testing to verify the algorithm. yes, the code is retrieving huge amount of data. basically it involve nested loops and it will stop if 2 values are matched.
let me tell a bit of this system. this system is about soil test proficiency. whereby 1 soil test with 15 parameters will be conducted by 30 soil laboratories. 1st test involved 1 soil test with 1 parameter and 30 labs, the result was good. and today i test the algo again but this time involving 3 parameters and 30 labs. then i started to produce an error regarding memory allocation.
Last edited by wackyflik : January 9th, 2013 at 03:06 AM.
Posts: 377
Time spent in forums: 1 Week 3 h 27 m 44 sec
Reputation Power: 293
Quote:
Originally Posted by wackyflik
thanks for the suggestion but I still get the same error. I did change to memory_limit = 2048M but it still produces the same error. However, the error pointed to different line of code. This time at line 107.
At a guess, when you change it to 2048M the error said 2147483648 bytes exhausted?
If the line changes, all it means is that the code is getting to line x, where it tries to allocate some more memory, but it can't as it's already using all it can.
If 1 PHP script is trying to use more than 2GB of memory you have a big problem. Best guess would be that there may be an infinite loop somewhere, or you really really need to optimise your code.
Think of it this way. Assuming your script uses 2GB of ram to execute. If you had 10 people hit the page at the same time, you would need to have 20GB of ram available for the server to throw at the php processes. On top of that you have all the other pages which are trying to be served from the server etc. Your server will end up swapping like crazy which will cause higher I/O load on the CPU, thus more than likely cause a load spike.
Posts: 377
Time spent in forums: 1 Week 3 h 27 m 44 sec
Reputation Power: 293
Quote:
Originally Posted by wackyflik
Fatal error: Out of memory (allocated 1997012992) (tried to allocate 35 bytes) in D:\website\root\aglam\aglam_soil_comm_func.php on line 628
Same problem as my other replies. In english the error is saying "I got to line 628 and tried to ask for 35 bytes of memory, but I have already used 1997012992 bytes (~1.9GB) so I can't.
How much data are you trying to deal with? How much data are you expecting to get back from the DB? If you are legitimately getting back gigabytes of data from the DB, and you need all of that data, then you will need to look at putting that limit up as high as you can, and hope the server has got the grunt to deal with the load. If you don't need all of the data coming back from the DB, then refine your query.
Instead of copying parts of an array to other / new arrays, reference the original array when you can. That'll prevent more memory being used to store the same data.
Posts: 259
Time spent in forums: 4 Days 55 m 36 sec
Reputation Power: 0
no of raw data: 1 soil sample * 15 parameters * 30 labs = 450 processed data. however, the data processing will continue until 2 values of Robust Mean and Robust Standard Deviation are matched. therefore no of data will be exceed than 450. i attached together successful processed data that being tested.
Posts: 2,041
Time spent in forums: 1 Month 2 Weeks 6 Days 22 h 46 m 55 sec
Reputation Power: 812
Quote:
Originally Posted by ptr2void
php Code:
Original
- php Code
while($loop = true)
It's not an infinite loop as far as I can tell, because he also makes a "break" when he sets $loop to false (which makes the whole $loop thing pointless, of course).
But I agree that the code looks rather strange and has plenty of security holes. I wouldn't be surprised if that's the reason for your memory issue.
In fact, when you get errors like that, your first reaction should be to check your script and repair/optimize it, not increase the memory limit!
Posts: 259
Time spent in forums: 4 Days 55 m 36 sec
Reputation Power: 0
Quote:
Originally Posted by ptr2void
php Code:
Original
- php Code
while($loop = true)
Look closely there.
thanks for the idea. that line is at line no 94. there are 2 lines at 152 & 153 to stop the loop and continue with further process. i got headache fixing the code all night but still can't fix it.
Posts: 2,041
Time spent in forums: 1 Month 2 Weeks 6 Days 22 h 46 m 55 sec
Reputation Power: 812
Quote:
Originally Posted by wackyflik
there are 2 lines at 152 & 153 to stop the loop and continue with further process.
Yeah, but what's the whole point of $loop? It's always true until right before you break the loop, so it has absolutely no effect.
I guess you did confuse "=" and "==" and at the same time couldn't decide whether to control the loop with the $loop variable or with an explicit break. You cannot use both, this simply makes no sense.
Another oddity is the "while" loop in line 265:
PHP Code:
while($countColFooters < ($maxColFooters))
{
if($countRowFooters == 0) //1st row
do A;
elseif($countRowFooters == 1) //2nd row
do B;
elseif($countRowFooters == 2) //3rd row
do C;
elseif($countRowFooters == 3) //4th row
do D;
elseif($countRowFooters == 4) //5th row
do E;
if($countColFooters == ($maxColFooters - 1))
do F;
$countColFooters++;
}
Um, how is that different from simply doing A, B, ..., F one after another ??
PHP Code:
do A;
do B;
do C;
do D;
do E;
do F;
Also, use for loops for counting stuff.
Another big problem I already mentioned is that your script is open to all kinds of SQL injections and XSS attacks, because you just happily dump the user input into your database queries and HTML markup.
Wait, you do occasionally use mysql_real_escape_string() in the first few lines (though I'm not sure if it makes sense in this context). Why there but not where you actually need it?
No offense, but this code looks like you totally rushed it without really thinking everything through. If you have any chance to work on it for some more days, then that's what you should do. You'll need to rewrite several parts.
You might also have to get clear about some PHP basics. For example, this "$bool == true" in "if" statements and "while" loops makes absolutely no sense. A boolean value already is true or false, it doesn't get "truer" or "falser" by putting it into a condition. Just use "if ($bool)" and "while ($bool)" respectively.
Last edited by Jacques1 : January 10th, 2013 at 12:13 AM.
Posts: 377
Time spent in forums: 1 Week 3 h 27 m 44 sec
Reputation Power: 293
I have to agree with Jacques1, the code is not the best.
How do you fix your problem? Again, echoing on from Jacques1 a little bit, start again. Sit down with a white board, or pen and paper or whatever, map out exactly what your end result needs to be, and what data you need from the DB. Break everything down into smaller steps / functions and then get a clear picture in your head as to how all that fits together. When you know exactly how it all needs to work, then you start coding.
While you are coding, keep these things in mind:
- use PDO instead of mysql_*
- think hard about data storage. I saw a lot of spots in your code where you were copying elements from 1 array to another, which you may not need to do.
- lastly, and probably most importantly, really think about how your loops work. You have a lot of them, and they are the most likely cause of the excess mem usage IMO.
There are also a couple of functions you can use to check what is happening memory wise: