Reputation: 33
im using this code:
<!-- Progress bar holder -->
<div id="progress" style="width:300px; height:20px; border:1px solid #ccc; float: right; margin-top: 7px; margin-right: 7px;"></div>
<!-- Progress information -->
<div id="information" style="width; text-align: center; margin-top: 7px;"></div></div>
inside a while loop:
// Javascript for updating the progress bar and information
echo '<script language="javascript">
document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\"> </div>";
document.getElementById("information").innerHTML="'.$i.' av '.$no_lines.' rader processade.";
</script>';
// This is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
// Send output to browser immediately
flush();
$i will increase with +1 every time the while loop does something, this can be very large. upwards of 300k. and currently the code crashes at ~14000 (memory usage is above 1gb ram then). it also hovers at around 30% cpu usage and makes internet usage very unpleasant while uploading
ive never worked with javascript before, and ive read up about memory leaks in javascript, however it doesnt help me with how i prevent this. i found some links which help me sort of, however i dont know how to apply them to my code http://javascript.info/tutorial/memory-leaks for example: empty(), remove(), removeData(). i also looked at this post: http://www.javascriptkit.com/javatutors/closuresleak/ it was helpful to understand what was happening but couldnt figure out what i did wrong. currently im only doing the code if $i % 100 == 0 which is so bad im not even proud of that "solution".
could anyone of you help me prevent the memory leak in my code?
Upvotes: 0
Views: 105
Reputation: 6359
You're continuously sending script blocks to the client, so your markup will grow forever.
In reality, you should probably use AJAX to call to a PHP page (or whatever server technology) to get the data you require.
This approach also stops the PHP process from being so "busy" continuously keeping an HTTP request alive.
If you used jQuery and AJAX, you just need a function that calls every X seconds e.g.
var myTimer = setInterval(2000, getData);
function getData() {
$.ajax({
url: "http://getData.php",
dataType: json})
.done(function( data ) { // data is the parsed json
$("#progress").html(data.percentage);
$("#information").html(data.information);
}
});
}
Where the json looks something like
{
percentage : 80,
information : "some more info"
}
If you need a more "real-time" update, then you should use one of the methods of implementing COMET. You could just use a long-held HTTP request in the case above, with a timeout that re-requests the URL (which isn't great for PHP, better for other technologies).
Upvotes: 0
Reputation:
It looks that what is happening, is you are appending more and more <script>
tags to your document
. Instead, try placing this code in your while
:
<script language="javascript">
var progress = document.getElementById('progress'),
information = document.getElementById('information');
progress.style.width = $percent;
information.innerHTML= $i + ' av ' + $no_lines + ' rader processade.';
</script>
Looking at your variables and function names, it also looks like PHP, not the javascript. In this case, you should use setTimeout
function instead of while
and request progress update via AJAX.
Upvotes: 0
Reputation: 155015
(Disclaimer: I'm a software engineer at Microsoft who works on the Internet Explorer Javascript engine "Chakra"):
Your Javascript code does not contain any loops which create new objects, so there is no risk of you leaking memory, though your use of innerHTML
instead of direct DOM manipulation presents an opportunity for performance optimization (as using innerHTML
causes the text to be parsed and processed which isn't a cheap operation, calling setAttribute("style", "width: ...
is a lot cheaper.
As I wrote in my comment-reply to the question, I don't recommend the approach you're using to send progress updates to the client. This approach is known as Comet ( http://en.wikipedia.org/wiki/Comet_%28programming%29 ). But advising alternative approaches is off-topic and you haven't explained any details about this background-operation your code is executing so I'll refrain from further comment.
Upvotes: 2