Javascript memory leak in recursive polling method - javascript

Actual problem that needs solved: I'm working on a large application, the initial release of which was about two years ago. We're now adding a new page to the application, and noticing some odd behavior. The new screen is going to be an "always-on" status screen, meaning it is the default screen in the app and the dedicated pc the app runs on will always display it by default. After a certain amount of time (only a few minutes on IE, usually much longer on Chrome) things start misbehaving. First, the animation of the scrolling messages (if any) becomes choppy and slow, eventually to the point that they appear to move about 1 pixel/second. The choppiness begins in minutes in IE on the machines we use, and within a couple of hours will be slowed to a crawl. By that time, the other odd behavior has started: the browser itself will be slow to react. There is a menu/login button on this screen, and there is a delay of 3-4 seconds before anything happens when it is clicked. Other visual elements have a similar delay before updating, even though they have no interaction with the user.
I and others on the team have spent several days looking at everything on this page, and think we have the cause narrowed down to what appears to be a memory leak within the service we use for polling data. It appears on each page in which we use the service, but we believe that the symptoms are only an issue on the new screen because of the large number of visual cues (scrolling, updating icons/colors, etc.), many of which have some intensive processing/graphing that runs every cycle when the data is updated, and the fact that no one is likely to have left the other screens up and running for the length of time it may take to start to see symptoms on a less hard-working page.
I took a timeline screenshot in Chrome's developer tools, and this is what it looks like. It looks similar on each page that uses our polling service.
I created a demo of just the polling, and got a similar graph:. It appears a little less severe in the demo, but the pattern is obviously similar, and looks like a memory leak. How can we resolve the memory leak and eliminate our other issues?
Some relevant code:
var reload = function() {
$http({
method: 'GET',
url: 'api.txt',
timeout: 5000
})
.success(function(response) {
//do stuff
})
.error(function(data) {
//do other stuff
})
.finally(function() {
timer = $timeout(reload, 1000);
});
};

are you using closures somewhere in your code?
Since these type of problems occur only while using many closures because that is the place in java script where object is not destroyed, if you use too many closures eventually you will run short of memory.

Related

JavaScript clean memory

I have a problem about memory management.
My simpliest code is here:
var url="/abrapo.php";
var ob={start_:100, token:null}
function post_token(){
$.post(url,{access:ob.token})
.done(function(data){
console.log(data);
ob=data;
});
}
I call function post_token every seconds. So after 2000 call user has problem of memory, ram goes up to 2GB. I don't need to save anything just want to log data after post and clear memory. I've already googled and find delete ob. But it does not clean the memory. What increase memory and how can I clean it without reloading the page
Use your browser's profiling tools to determine where you're accumulating memory. In Chrome these profiling tools are located under the Performance tab in the Chrome Developer Tools F12.
Click the Memory checkbox near the top to enable memory profiling
Click Start Profiling and Reload Page (Ctrl+Shift+E)
Let the profiling run for a while, most pages load in 2-3 seconds but it sounds like your page needs to run longer than that
Click the Stop button to halt the profiling
Among all the other performance graphs, you should see one for memory usage that looks something like this.
You can use this to see if, and when, the browser is performing garbage collections on the Javascript heap. You may need to manually clear certain objects by setting them to null. Also, try to avoid cyclical references and other complex referencing patterns that could cause the javascript engine to hold on to objects longer than it has to.
Click here, for more about the memory management and garbage collection in the browser.
I had similar problems while writing UI for a data acquisition device and managed to make it fly by setting every variable containing large data arrays to null whenever not used.
Your use case isn't easy to replicate with just your code, but I suggest you try setting
data = null;
and
ob = null;
whenever not in use.
You might have to tweak suggestion a bit, say by assigning only token:
ob.token = data.token;
in such case only token would have to be set to null
ob.token = null;
What this achieves essentially is that it gives garbage collector a chance to clear unused objects since variables using those were clearly set to null. Oh, yes, and memory profiling is your friend to find out what exactly should you null
According to your code example, the problem is with console.log(data)
it make your object accessible from Console. The Garbage collection will free memory only when the object is no more accessible.

Performance issue in react js

I am currently using reactJS version "15.0.1" in my web application. In one of the feature we need to keep pooling some information continuously after each 2 seconds. So we receive the response which is List of some object(700/1000 items in list) which we update and show in the react web application. The Problem is after some time the application becomes unresponsive and takes too much time for any operation. On profiling I found its render, batch updates and dispatch event in react js that takes the longest time. Is there any recommended way to get away with the performance issue in react. The feature needs to be refreshed every 2 seconds and list size is more than 1000 items each time.
The performance issue is observed in IE and Chrome browser.
It's hard to tell without seeing your code, maybe you have a memory leak? You could try to mark your objects for garbage collection at the end of your methods.
listOfSomeObject = null;
Here is a good article capturing some methods to identify and fix memory leaks.
https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

Empty requestAnimationFrame loop leaking memory?

I have a clean HTML file with requestAnimationFrame loop that does absolutely no processing. However, if I look at memory consumption on Chrome DevTools I see that used memory constantly increases and garbage collector runs every few seconds to collect around 1 megabyte of garbage data.
So where does this memory leak comes from?
That's how my memory usage looks like:
And here's my code:
<!DOCTYPE html>
<html>
<head lang="en">
<title></title>
<script>
function update() {
window.requestAnimationFrame(update);
}
update();
</script>
</head>
<body>
</body>
</html>
I investigated this too. I came here because I noticed Chrome is tracking where calls come from.
And I noticed it was going all the way back to the original call
So, I left it running for an hour checking on it every few minutes. It did allocate memory for a while but eventually seemed to release some.
I'm pretty sure it does this to make debugging other async code easier since it's helpful to know where some async request started. Without that path all you get is that your event/callback got called, not where it was created.
That said I understand your pain. It's well known that 24fps has problems and movie directors tend to avoid the types of scenes that show those issues. When "The Hobbit" came out and was shot at 48fps the director tried adding some of the types of scenes back in that fail at 24fps.
It's also well known in video games that 30fps is not enough for any 2d scrolling game. For into the screen games it's passable (whole generations of games shipped at 30fps on PS1, PS2, N64) but for 2d scrolling games the entire screen appears to shutter at 30fps where as it appears smooth at 60fps
In any case I don't have a solution to suggest. It's just the way the browser works. Every time you create an event, which is what requestAnimationFrame does, some small object has to be allocated and put on the list of events to be executed at some point in the future and that in itself takes memory. For requestAnimationFrame in particular maybe the browser could special case having only a pre-allocated queue of a few events and trying to recycle them rather then use the generic system they use for all other events (mouse, keyboard, images loading, XHR requests finishing etc) but that would likely be hard to implement given that when the events actually execute they probably need to be in the same queue.
And even then, JavaScript itself is all about allocating memory. It's nearly impossible not to. Calling a function allocates the arguments since they end up being part of that function's closure context (JS engines might optimize that but from language perspective they allocate).
Now that browsers are starting to target WebVR which requires 90fps maybe they'll come up with a new way. Or maybe we'll all switch to WebAssembly?
¯\_(ツ)_/¯

Javascript Timed Notifications - setTimeout, setInterval

I am creating a web app that allows users to manage a calendar (CRUD events, tasks, reminders etc...)
And I am trying to implement a feature where they will receive a popup reminder x-minutes before the event/task. From my understanding there is really only one way to do this with javascript:
On login, check for any upcoming events in the database (say in the next 12 hours) and create a setTimeout for the next event, when that setTimeout executes, check again for next event and so on...
My question is, will having multiple setTimeouts (10+) running in the background during user interaction slow down the performance of my app?
Is there a better way to handle popup notifications on the client side? Push Notifications? Any suggestions would be greatly appreciated!
My question is, will having multiple setTimeouts (10+) running in the background during user interaction slow down the performance of my app?
In those numbers, no. (Depending on how + the + in 10+ is. I mean, I expect a million probably would be an issue.)
The other approach would be to have a single timer that you use (say, per minute) to check for notifications that should occur as of that minute. E.g.:
function notifyForThisMinute() {
// Notify user of things we should notify them of as of this minute
// ...
// Schedule next check for beginning of next minute; always wait
// until we're a second into the minute to make the checks easier
setTimeout(notifyForThisMinute, (61 - new Date().getSeconds()) * 1000);
}
notifyForThisMinute(); // First call starts process
This depends on the browser (or more specifically, it's javascript engine) and apparently even OS.
Neil Thomas (while working on GMAIL mobile) and John Resig have analyzed timers.
One of the more noticeable things to look out for is how often the timer runs per given time-interval (say every 200ms or once every 10 minutes..).
Thomas:
With low-frequency timers - timers with a delay of one second or more - we could create many timers without significantly degrading performance on either [an Android G1 or iPhone 3G]. Even with 100 timers scheduled, our app was not noticeably less responsive. With high-frequency timers, however, the story was exactly the opposite. A few timers firing every 100-200 ms was sufficient to make our UI feel sluggish.
Thomas:
Keep in mind that this code is going to execute many times every second. Looping over an array of registered callbacks might be slightly "cleaner" code, but it's critical that this function execute as quickly as possible. Hardcoding the function calls also makes it really easy to keep track of all the work that is being done within the timer.
Resig:
Once you start moving into the range of 64-128 simultaneous timers, you’re pretty much out of luck in most browsers.
One might also have a look at Chronos

“Recursive” timeouts in AJAX callbacks fill up memory. How can I avoid this?

I am working on a dashboard project where multiple widgets (like a dozen) need to be updated via an AJAX source every 5 seconds or so. I am currently using setTimeout to queue a widget update, which is called everytime the widget is actually updated (not technically a recursion, but…). This is how the code looks
var update;
(update = function() {
$.get(source, function() {
// Do something
setTimeout(update, 5000);
});
})();
After a few hours of the page running (Chromium 21), it can easily OOM my 8GB RAM.
As the client uses IE6 on very small configurations (< 1GB RAM), the issue is even more important.
How could I avoid this quirk?
Ok, thanks freakish & Pointy, the leak was indeed caused by jqPlot. Thing is, you have to use the .destroy() method on said plot, and then remove (and not empty) its DOM container, before creating another one and redrawing a plot.
Use setInterval instead. That way you only generate one timer and don't need to start a new one every five seconds, which might consume some sort of handle in the browser.
I actually wouldn't have thought setTimeout to leak, but there is a clearTimeout function. Just for researching purposes you could try saving the returnvalue of setTimeout and clearing it, before starting the next one.

Categories

Resources