Why is navigator.cpuClass incorrect? - javascript

I am trying to acquire the CPU type of visitors from Javascript using navigator.cpuClass in order to offer them the correct download. In my tests I have run into an example of navigator.cpuClass returning "Win32" when expect "Win64". The systeminfo utility on my PC returns:
Intel64 Family 6 Model 15 Stepping 11 GenuineIntel ~2400 Mhz (Q6600) which is further described at:
http://ark.intel.com/Product.aspx?id=29765
Can anyone tell me why Javascript is not seeing a 64 bit CPU? I need to reliably detect that CPU...

Perhaps you are using a 32 bit browser. Trying out the samples from here, I get the same results (Win32) even though I'm running a 64 bit OS (with a 32 bit build of Chrome).
However, in my case, Chrome's appVersion string indicates that it runs under the Wow64 emulation layer. Perhaps you can find such hints for others browsers as well.
Generally, you can't detect the CPU class reliably because you never know whether your browser took the red or the blue pill.
A pragmatic solution would be to offer a default choice based on what your browser returns, and allow the user to switch to a 64 bit version. Since most 32 bit software runs flawlessly in a 64 bit environment (as proved by this case), most users won't notice if they pick the 'wrong' download.

Related

Is there any memory limit for Google Chrome browser?

What is the default memory limit for a single tab in chrome ??
It's hard to answer correctly and the answer could be figured out only in benchmarks for particular task with particular build.
There are several thing that could allow you to use from 1 to 2 GB of memory:
Chrome version: because different V8 engines have different memory limits.
Chrome platform: 32-bit or 64-bit.
Operating System itself: chrome could be built with different flags for different platforms.
Again, Chrome version: there are some discussion on the internet about recompiling chrome with some compilation flags that could allow to use more memory, then chrome developers decide to exclude such flags because of some reasons. Who know — maybe they will include them again or will increase default heap size.
Video memory: in some cases page's content may require some video memory and, if your video adapter has no sufficient amount, Chrome will take it from general memory, which will increase memory usage for the page.
Right now, with 64bit Chrome version 47, on Windows 8.1 I can take up to 1.8GB with one tab, then it crashes.
Update:
As I can see some magic has happened and limit has changed.
For Chrome version 63, on x64 Windows 10 OS, I could allocate up to 3.5 GB memory, parsing a huge JSON string and then displaying it on the page.
The number is taken from Chrome's Task manager and from Process Explorer's Private Bytes metric.
There was some talking about a very similar topic. Here
You should try the following:
Right click on the Chrome icon and go to properties. Chrome should be here:
"C:\Documents and Settings\%USER%\Local Settings\Application Data\Google\Chrome\Application\chrome.exe"
Where %USER% is your username on your PC, obviously ;)
At the end of the line add --purge-memory-button
It should look like this:
"C:\Documents and Settings\%USER%\Local Settings\Application Data\Google\Chrome\Application\chrome.exe" --purge-memory-button
Now, when Chrome works, press shift+Esc, and now you have a new option, "Purge Memory" which frees up memory. The tabs that do not need attention at that particular time will be purged from your RAM.
You can also add one of these lines:
Never voluntarily relinquish memory
--memory-model=high
Voluntarily reduce working set when switching tabs
--memory-model=medium
Voluntarily reduce working set when switching tabs and also when the
--memory-model=low
Browser is not actively being used
You can have several lines after the target place "C:\Documents and Settings\%USER%\Local Settings\Application Data\Google\Chrome\Application\chrome.exe"
Let's say we wanna use the "Purge memory" line and the "Low memory model" line. It would look like this:
"C:\Documents and Settings\%USER%\Local Settings\Application Data\Google\Chrome\Application\chrome.exe" --purge-memory-button --memory-model=low
You can have a perfect answer once you benchmark on a specific platform with a specific version. The outcome will only be applicable to that platform and chrome version you experimented because there is so many factors that may have a different effect in results including,
The Chrome Version may have different v8 engines and not all v8 engines have the same memory limits. Also, the 32 bit and 64-bit architecture come into picture when we benchmark the chrome. The default heap size may varies from v8 version to version.
The system configuration on which you run the chrome. chrome requires the graphics memory/video memory and when you don't have that, It will use internal memory resulting in more memory usage.
It's also related to process itself, every thread requires some memory for bookkeeping, notably its stack. 32-bit processes can only address 4 GB of memory. 64-bit processes don't have problems with address space, but rather with the actual allocations. However, programs should not approach any such limit or need to worry about it and the same applies to chrome as well.
I tried once to export and print the database from PHPMyAdmin from chrome. It had 1.22GB of size in DB and chrome crashed. Same thing I performed to file export and magically it worked fine.
About the v8 engine, it has 512MB memory limit on 32bit system and 1434MB(1.4 GB) on 64bit system. The chrome has v8 it's heart, this is a major factor affecting the memory limit.
I was able to increase the memory limit for my nw.js (chrome) based destkop app by passing following command line options:
Node.js: node --max_old_space_size=12288 script.js
Google Chrome: chrome.exe --js-flags="--max_old_space_size=12288"
NW.js: add "js-flags": "--max_old_space_size=12288" to the package.json.
Adjust 12288 (12GB) to suit your needs
if you're running 32-bit Chrome, you can't allocate more than 2 GB, because that's the process limit for a 32-bit Windows process. for 64bit chrome there is 4gb limit.
Chrome doesn't allow allocations over 4Gb

How do you detect memory limits in JavaScript?

Can browsers enforce any sort of limit on the amount of data that can be stored in JavaScript objects? If so, is there any way to detect that limit?
It appears that by default, Firefox does not:
var data;
$("document").ready(function() {
data = [];
for(var i = 0; i < 100000000000; i++) {
data.push(Math.random());
}
});
That continues to consume more and more memory until my system runs out.
Since we can't detect available memory, is there any other way to tell we are getting close to that limit?
Update
The application I'm developing relies on very fast response times to be usable (it's the core selling point). Unfortunately, it also has a very large data set (more than will fit into memory on weaker client machines). Performance can be greatly improved by preemptively loading data strategically (guessing what will be clicked). The fallback to loading the data from the server works when the guesses are incorrect, but the server round trip isn't ideal. Making use of every bit of memory I can makes the application as performant as possible.
Right now, it works to allow the user to "configure" their performance settings (max data settings), but users don't want to manage that. Also, since it's a web application, I have to handle users setting that per computer (since a powerful desktop has a lot more memory than an old iPhone). It's better if it just uses optimal settings for what is available on the systems. But guessing too high can cause problems on the client computer too.
While it might be possible on some browsers, the right approach should be to decide what limit is acceptable for the typical customer and optionally provide a UI to define their limit.
Most heavy web apps get away with about 10MB JavaScript heap size. There does not seem to be a guideline. But I would imagine consuming more than 100MB on desktop and 20MB on mobile is not really nice. For everything after that look into local storage, e.g. FileSystem API (and you can totally make it PERSISTENT)
UPDATE
The reasoning behind this answer is the following. It is next to never user runs only one application. More so with counting on the browser having only one tab open. Ultimately, consuming all available memory is never a good option. Hence determining the upper boundary is not necessary.
Reasonable amount of memory user would like to allocate to the web app is a guess work. E.g. highly interactive data analytics tool is quite possible in JS and might need millions of data points. One option is to default to less resolution (say, daily instead of each second measurements) or smaller window (one day vs. a decade of seconds). But as user keeps exploring the data set, more and more data will be needed, potentially crippling the underlying OS on the agent side.
Good solution is to go with some reasonable initial assumption. Let's open some popular web applications and go to dev tools - profiles - heap snapshots to take a look:
FB: 18.2 MB
GMail: 33 MB
Google+: 53.4 MB
YouTube: 54 MB
Bing Maps: 55 MB
Note: these numbers include DOM nodes and JS Objects on the heap.
It seems to be then, people come to accept 50MB of RAM for a useful web site. (Update 2022: nowadays averaging closer to 100MB.) Once you build your DOM Tree, fill your data structures with test data and see how much is OK to keep in RAM.
Using similar measurements while turning device emulation in Chrome, one can see the consumption of the same sites on tablets and phones, BTW.
This is how I arrived at 100 MB on desktop and 20 MB on mobile numbers. Seemed to be reasonable too. Of course, for occasional heavy user it would be nice to have an option to bump max heap up to 2 GB.
Now, what do you do if pumping all this data from the server every time is too costly?
One thing is to use Application Cache. It does create mild version management headaches but allows you to store around 5 MB of data. Rather than storing data though, it is more useful to keep app code and resources in it.
Beyond that we have three choices:
SQLite - support was limited and it seems to be abandoned
IndexDB - better option but support is not universal yet (can I use it?)
FileSystem API
Of them, FileSystem is most supported and can use sizable chunk of storage.
In Chrome the answer is Sure!
Go to the console and type:
performance.memory.jsHeapSizeLimit; // will give you the JS heap size
performance.memory.usedJSHeapSize; // how much you're currently using
arr = []; for(var i = 0; i < 100000; i++) arr.push(i);
performance.memory.usedJSHeapSize; // likely a larger number now
I think you'll want something like the following:
const memory = navigator.deviceMemory
console.log (`This device has at least ${memory}GiB of RAM.`)
You can check out the following: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/deviceMemory
Note: This feature is not supported across all browsers.
Since a web app can't have access to any system-related information (like the available amount of memory), and since you would prefer not having to ask users to manually set their performance settings, you must rely on a solution that allows you to get such information about the user's system (available memory) without asking them. Seems impossible ? Well, almost...
But I suggest you do the following : make a Java applet that will automatically get the available memory size (e.g. using Runtime.exec(...) with an appropriate command), provided your applet is signed, and return that information to the server or directly to the web page (with JSObject, see http://docs.oracle.com/javafx/2/api/netscape/javascript/JSObject.html).
However, that would assume your users can all run a Java applet within their browsers, which is not always the case. Therefore, you could ask them to install a small piece of software on their machines that will measure how much memory your app should use without crashing the browser, and will send that information to your server. Of course, you would have to re-write that little program for every OS and architecture (Windows, Mac, Linux, iPhone, Android...), but it's simpler that having to re-write the whole application in order to gain some performance. It's a sort of in-between solution.
I don't think there is an easy solution. There will be some drawbacks, whatever you choose to do. Remember that web applications don't have the reputation of being fast, so if performance is critical, you should consider writing a traditional desktop application.

Odd console.memory results in Chrome, negative numbers in timeline memory dev tools, a Chrome bug?

After running for a very long time (a day or more) a web-based app I wrote (JS/HTML5) starts acting "weird". Primarily it stops sending the normal data it should to the backend, where I expect it to be sending ~500kb of data it starts sending just a few bytes of nonsense. I suspected this was memory related (unable to allocate memory or something?) and when I investigated I saw something truly strange and seemingly impossible, which suggests to me that it's a Chrome bug I'm encountering perhaps through high memory usage. But I could use some confirmation from someone who knows better than I do.
The main oddness seems to be what console.memory spits out. The linked document says that "usedJsHeapSize can not be greater than totalJsHeapSize" which it very, very much is. It's also higher than the heap size limit, which I imagine it should not be:
I then tried to see what devtools might tell me and did a timeline of memory at that instant, for a few seconds, and look at what it says.... the memory ranges from some negative insanely big number to 0B. That sure doesn't seem right.
And I checked the chrome://memory report and while it is using a lot of memory, comparing that to other Chrome browsing sessions I have going it doesn't seem freakish.
Can anyone confirm this is a Chrome bug versus expected dev tools behavior I'm not interpreting correctly.
Thanks!
Values are bucketed to prevent side-channel attacks
Bucketing described here: http://goo.gl/fFspKO
Get precise numbers with Chrome flag: --enable-precise-memory-info

Javascript Speed - Chrome v Firefox

I wrote this small game at http://amarnus.me/games/dodge. Now if you trying playing the game in both Firefox and Chrome, you would clearly notice that it is significantly slower in Firefox. You can call it an unintentional cheat code, yes. ;-)
So my question is - Is this because of a slower Javascript engine in Firefox when compared to Chrome's? Or does it have something to do with bad coding? (In my defence, I am a Javascript newb)
Assuming that it is the former, then is this not a point against (disadvantage of) HTML5 games? (The ones using the <canvas> tag like mine)
Firefox is slower than chrome in javascript. However, I believe that it's also slower using the canvas-tag. This will probably improve with ff4 (have you tried the beta?).
There is also a nes emulator out on the web somewhere using js and canvas, and it runs in about 30fps on chrome (if I remember about correctly), but only about 10 in ff.
Time is probably your best friend :-P, though you can alwasy try to optimize.
I believe that browser-games will come in time, but it's not ready as of yet to anything too advanced. Maybe about the time ie12 comes out :-P.
[Edit]
Btw: I tried the game in FF4b1, and I thought it ran great. Probably not as fast as in chrome, but not far from it :).
In order to get help you might consider providing a non-minified version of your script.
I see that there are 8ms setIntervals in your code. As mentioned above, Firefox never goes below 10 ms (yet). Playing your game in FFox 4 it is very enjoyable, though. I saw two very small hickups that clearly were caused by garbage collection. Chrome has an edge over the Fox in that regard. Even though SpiderMonkey (that handles GC in Firefox) has improved dramatically from 3.5 to 3.6 it's still not good enough for many games. In 4.0 it is a lot better, but still not quite as good as in Chrome or Opera. (It is being worked on.)
Playing the game and looking briefly at your code, I see no complexity that would cause Firefox not to be able to handle what's going on. Also Firefox 4 has hardware accelerated Canvas that is marginally faster than IE9 and a lot faster than Chrome.
There is a notion on the web that Chrome is faster than Gecko when it comes to canvas, but that is because people rarely profile their pages. In fact, canvas in Firefox 3.6 is already at least as fast as in Chrome, but many tests don't show it since the JavaScript is slower. (And some JavaScript tests are slower because Firefox does not handle the test harness well.)
All this leads to lots of confusion and misinformation. The bottom line is that your game should be OK in Firefox 4. You should see if there is anything you can do to avoid triggering unnecessary GC. E.g. are you re-using variables or creating unnecessary new ones?
However, in Opera 10.53 it was not enjoyable. Not because Opera could not keep up with the speed, but since instead of moving the bottom piece, it was kept stationary and the whole playing field moved instead. (I managed to go to level 17 in my first try in spite of this.) In Opera 10.6 the page fails to load properly.
You probably need to debug your code - or perhaps file a bug with Opera if it's a regression. (I'll tweet this to get their attention.)
I'd blame a large part of it on setTimeout and setInterval having a ~10ms minimum in browsers such as IE and Firefox. This was originally adopted to stop pages from consuming the entire CPU should they naively use 0ms to run as fast as possible. Chrome launched without a limit but is now moving to a 4ms minimum to match the recommendation in HTML5.
John Resig has some awesome posts investigating setTimeout limits and accuracy.
Mozilla browsers can actually tell you how late (or early!) they're running with each setInterval call. Check out the MDC setTimeout article (google "mdc settimeout" and check out the grey note in the syntax section).
Apart from timer problems, Firefox is just generally slower in JS execution (for now at least) and it feels as if Skia (Chrome's graphics lib) is just faster at rasterising too.
Hope this helps :)
(I originally had a bunch of useful links here, but it's my first post and the spam filter slapped me down.)
jQuery animate does something similar to your DOM object movement.
I would look into their code and see how they do the actual movement, it's probably the most efficient way since it's built in jQuery.
Chrome is designed to have a faster Javascript engine.
I don't think it says anything about HTML5 games. You will always find users with faster or slower setups than others, be it hardware, software or a user's personal habit of keeping many applications running at once. If your game were written in Flash or Java, then a user with slower hardware would see a similar slowdown.
You may be able to make changes to your code in order to speed it up. I haven't examined it in great detail, but I see you have constructs like if(dodge.goRight == true .... Although not a source of slowness, this does hint that you may not have used the optimal solution everywhere.
You can test your browser javascript engine with IE site.
http://ie.microsoft.com/testdrive/
They assert to the highest speed javascript engine they have with IE9
Try out this technique: setTimeout with a shorter delay
Let me know if it helps. I'm kinda curious now. :)
Good luck!

How does any application (chrome, flash, etc) get a time resolution better than the system time resolution?

This article on Microsoft's tech net site supplies an exe that will calculate your windows machine's minimum time resolution - this should be the smallest "tick" available to any application on that machine:
http://technet.microsoft.com/en-us/sysinternals/bb897568.aspx
The result of running this app on my current box is 15.625 ms. I have also run tests against Internet Explorer and gotten the exact same resolution from the Date() javascript function.
What is confusing is that the SAME test I ran against IE gives back much finer resolution for Google's Chrome browser (resolution of 1ms) and for a flash movie running in IE (1ms). Can anyone explain how any application can get a clock resolution better then the machine's clock? If so, is there some way I can get a consistently better resolution in browsers other then Chrome (without using flash)?
The first answer below leads to two other questions:
How does a multi-media timer get
times between system clock ticks. I
imagine the system clock as an
analog watch with a ticking hand,
each tick being 15ms. How are times
between ticks measured?
Are multimedia timers available to
browsers, especially Internet
Explorer? Can I access one with C#
or Javascript without having to push
software to a user's
browser/machine?
You can get down to 1 ms with multimedia timers and even further with QueryPerformanceCounter.
See also GetLocalTime() API time resolution.
EDIT: Partial answer to the new subquestion ...
System time resolution was around 15 ms on the Windows 3 and 95 architecture. On NT (and successors) you can get better resolution from the hardware abstraction layer (HAL). The QueryPerformanceCounter counts elapsed time, not CPU cycles article, written by the Raymond Chen, may give you some additional insights.
As for the browsers - I have no idea what they are using for timers and how they interact with the OS.
Look at the timeBeginPeriod API. From MSDN: "This function affects a global Windows setting. Windows uses the lowest value (that is, highest resolution) requested by any process."
http://msdn.microsoft.com/en-us/library/ms713413(VS.85).aspx
(Markdown didn't like parens in the URL)
See "Inside Windows NT High Resolution Timers" referenced from the link you posted.
The APIC on the processor runs at bus speed and has a timer. They may be using that instead of the system time. (Or they might just be giving a bunch of precision that isn't there.)
This description of the Local APIC mentions using it as a timer.
(It may also be the case that there is some performance counter they are using. That actually seems more likely since a device driver would be needed to program the APIC.)

Categories

Resources