可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need to update a lot of data within a given interval with JavaScript. The problem is, no matter of what JS library i use (even bare-bone js), that all browsers seem to allocate memory on every AJAX request and are not able to free it afterwards. Here is a sample snipped that should reproduce the error:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Memleak Test</title>
<meta charset="utf-8" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript">
function readData() {
$.getJSON('data.php');
}
$(document).ready(function() {
setInterval(readData, 1000);
});
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>
An equivalent test page is available at jsbin
Here is more info on this:
- I also tried to put the readData() function as a closure directly in the setInterval() call. This doesn't seem to make any difference.
- I use jQuery here, but any other Library would produce the same errors.
- My data.php script just produces a fake JSON-Object with json_encode() in PHP.
- I know that one second is a short timeframe here, in my production script the timeframe is 30 seconds. I just wanted to see the effect quicker (in the production app it takes hours but then the memory is full too).
- The problem here is that the app will be open 24/7.
It seems so simple that I think I'm doing something really wrong here, it would be great if some of the JS gurus in here can help me out!
回答1:
One possible problem with the same posted is that if the XHR requests take longer than the poll period (on average) there will be an increasing queue of pending requests. If the web-server itself starts to backlog requests this can turn into a vicious cycle.
To avoid this possible case, use a CPS-style coding where the next action is done using the appropriate callbacks. That is, don't start the next request until required (previous request complete: success or failure) -- this approach can still be used to create a manual request queue with a controllable size if numerous outstanding requests are required.
Also, make sure that unused objects are be eligible for reclamation as this is the "standard" cause of a "memory leak" in a GC language.
Happy coding.
The code in the post contains nothing that will inherently leak memory. It could possibly be an issue internally with jQuery, but this is just speculation. Additionally, tools like Firebug that monitor XHR/web requests can consume significant amounts of memory so it's something to check and make sure the behavior is not a Heisenberg.
Also, remember that increasing memory usage doesn't not indicate a memory leak unless it grows unbounded. A garbage collection cycle will only occur when the hosts feels like it.
回答2:
Just a thought, instead of setInterval you should use setTimeout and then when it times out you set the timeout again.
That way you don't run the risk of the setInterval running off if you lose track of it for some reason:
- http://weblogs.asp.net/bleroy/archive/2009/05/14/setinterval-is-moderately-evil.aspx
I think also that the jquery ajax has a success callback which you can use as the point that you setTimeout. That way, as has been mentioned in this thread elsewhere, you dont end up overlapping requests.
- http://api.jquery.com/jQuery.getJSON/
(just checked and there is a success callback)
回答3:
you're polling sever after every second. Definitely it'll consume all of the memory. What however you can do is to set a predefined interval. Then after polling if the data is available fetch that and keep the interval same, but if after polling there is no data available yet, increment the interval to make sure next poll is delayed. This way you can reduce the load.
回答4:
Have a look at this post - might help ?
How can I force Javascript garbage collection in IE? IE is acting very slow after AJAX calls & DOM manipulation
(Suggests using specific JQuery methods that apparently try to avoid memory leaks: and using a 'delete' command to try and free up space).
回答5:
You will increase memory usage since you are loading more data on every request.
Clicky:
How to free memory after an Ajax request
Memory leak involving jQuery Ajax requests
回答6:
According to this jQuery forum thread:
...
success: function(data) {
// the line below prevents the leak, apparently
document.getElementById("theContainer").innerHTML = "";
$("#theContainer").html(data);
}
回答7:
Have you tried reusing the variables inside your calls? Meaning instead of making new variables where you handle the response, just use the same ones. Say
window.myvar = response["myvar"];
It it's really a leak, this might help the garbage collector. It would be nice to see the actual code of what you're doing though.