简体   繁体   中英

js memory leak on mobile

So, we've got memory leak in our mobile web application. It doesn't seen on desktop, but it crashes mobile Safari browser(iOS 4, 5, 6) and crashes whole Android OS (checked on versions 2.2.x).

Crash happens usually when site left open for a long time.

We use:

  1. headjs (for js loading)
  2. yepnope (for css loading)
  3. socket.io
  4. jquery mobile

So I have following questions:

  1. Which of the following libraries can cause memory leak?
  2. Should we review code that uses jquery selectors, or may be we should work carefully with socket.io?
  3. May script loaders(headjs, yepnope) cause memory leaks, if we load 20+ short scripts in them?

jQ mobile is known to cause leaks if you're not careful. All in all, I think all 4 of the toolkits you've listed could cause issues, especially when you're using them together.
Perhaps the best thing you can do is stick to one lib, as much as possible, and focus on using it in such a way that leaks are kept to a minimum. The problem with mobile browsers is that there's a lot more closure-magic going on, and the JS engines aren't that well known/understood (yet). If you've ever dabbled with writing JS event delegation code for touch devices, you must've noticed that there's just an incredible amount of closures, and DOM references that might not get GC'ed in time. There's not an awful lot you can do about this.

In general I tend to avoid using too many libs (I'm one of those ppl who will crawl to fire to avoid using any lib to be honest), so I might be biassed. But which ever way you put it: the combination of headjs and jQuery's tendency to check for the ready event in all ways you can imagine could be troublesome: you're dynamically loading new elements, have you checked if this triggers jQ's ready event multiple times? If it does, you're almost certainly binding the same handlers over and over and over again. Each ajax request might trigger the other toolkits to do the same thing, too, which might trigger jQuery again, which in turn might trigger the other libs again, which...
You got the picture. Though I'm far from an expert, my guess would be that the one lib might trigger the other and vice-versa, causing a deadlock scenario. I base this on a vague recollection of a similar issue I've encountered a while back, and the fact that you're using various libs to load scripts/CSS's dynamically, and the fact that jQ doesn't unbind all of its ready listeners last time I checked. If my hunch turns out to be right , you could use an evil global variable as a quick-fix:

var jQReady = false;
jQuery(document).load(function()
{
    if (jQReady === true)
    {//was loaded
        return;
    }
    jQready = true;//<-- set to true on first invocation of callback
});

Cool that you found your problem, but as Elias said, try reducing the number of frameworks you use.

Since JQ Mobile relies on jQuery anyways (so it's there when you need it), i would strongly suggest removing HeadJS & YepNope, and loading your resources with jQuery's $.get().

No need to include redundant functionality.

That said, i added css loading to the latest version of head, but honestly, if you already use jquery & don't use the responsive design parts, you don't really need it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM