Size of a variable in JavaScript
Out of interest, is it possible to determine the size of a JavaScript variable, in bytes?
I have a web-app that runs great on the desktop but blows up
* on the iPad. I'm guessing it's because there's a much more limited amount of memory in iPad Safari, but I'd like to get some idea of what's going on in my app.
I can estimate relative sizes, based on the size of the JSON source, but it'll be even better to know the actual size of the serialised object
- "Blows up开发者_如何学C" = Safari slows down, then the screen goes black, and I'm back to the standard iPad home screen. Whatever that's called. Looks to me, that Safari has run out of the memory allocated for a browser instance.
This won't directly answer your question. The JS language reference doesn't specify how to store data, so it's up to the groups doing the implementation, in this case the WebKit team, and I've not seen anything public on that. I've definitely not seen anything about Mobile Safari's implementation of WebKit.
What I would say is that things may actually not be running great on the desktop, it's just that the the desktop's speed and size masks "problems" that show up on the mobile devices. On iOS, a browser instance has a ceiling of 10MB in which to operate if I remember correctly, though in practice, you start to hit the wall right around 6 or 7MB. On a PC, when you run out of RAM, the computer will simply just dump out unused memory to the disk. On iOS either resources stop loading (such as images) or the browser just exits (which is probably what you are experiencing).
If you have a Mac, you can snoop on Safari to see how it's doing by using a tool called "Instruments" (it's part of the iOS SDK). If you don't have a Mac or don't want to download the SDK, just open a clean instance of Safari, open up Windows' Task Manager or Mac's Activity Monitor and watch how your memory usage changes when you load up your webapp.
Staying within the 6MB window is annoying. The biggest thing is try to avoid creating new images. For example, this pattern is a huge problem on an iPhone:
function placeImage(imagename,targetelement) {
var image = new Image();
image.src = imagename;
targetelement.appendChild(image);
}
In this case, even if you remove the image from the DOM, and even though image
is scoped within placeImage
, it will never, ever get released and it is just a matter of time before this application crashes the browser. If this is your case, instead think about how many images you need to display at once, create image objects only for those elements and recycle them (just reset the src
any time you want a new image).
Also, I've found that JavaScript's application stack is much smaller than on a desktop browser, so if you have a lot of recursion, you'll see the problem much faster on iOS. The way to spot this problem is to open up the Developer Tools in Safari and use the profiler to see what functions are getting called the most.
[edit] I can't remember if this is the exact technique that exposes how numbers are stored differently internally by webkit, but I think it is. Basically, you do a sort on a million random numbers, first with a float, then (if you uncomment the line) an integer and then a large integer. I'm not good with typed languages, so I'm not exactly sure what this proves other than that internally numbers are treated differently depending on their smallest possibly representation.
arrTarget = [];
for (var i = 0; i < 1000000; i++) {
arrTarget.push(Math.random() * 16000000);
// arrTarget.push(Math.floor(Math.random() * 16000000));
// arrTarget.push(Math.floor(Math.random() * 1600000000000));
}
// Time how long it takes to sort the array:
var time = new Date().getTime();
arrTarget.sort();
console.log(new Date().getTime() - time);
This isn't something you can do in general, but the sizes of some JavaScript objects are not implementation specific, so you do have some guarantees:
- "A string value is a member of the type String and is a finite ordered sequence of zero or more 16-bit unsigned integer values."
- "The type Number is a set of values representing numbers. In ECMAScript, the set of values represents the double-precision 64-bit format IEEE 754 values including the special "Not-a-Number" (NaN) values, positive infinity, and negative infinity."
Source
精彩评论