Browser JavaScript Stack Size Limit

Browser Javascript Stack size limit

Using a simple test:

var i = 0;
function inc() {
i++;
inc();
}

try {
inc();
}
catch(e) {
// The StackOverflow sandbox adds one frame that is not being counted by this code
// Incrementing once manually
i++;
console.log('Maximum stack size is', i, 'in your current browser');
}

Increasing stack size in browsers

You cannot alter the stack size in browsers, but you can use a trick called trampolining.

You can find a working code solution here:

How to understand trampoline in JavaScript?

How to avoid Maximum call stack size exceeded in JavaScript

You are simply making too many recursive calls and exceed the fixed limits. You can find those limits here: Browser Javascript Stack size limit. Each recursive function call adds one call to the stack and browsers do not handle 100.000 calls.

Maximum call stack size exceeded error

It means that somewhere in your code, you are calling a function which in turn calls another function and so forth, until you hit the call stack limit.

This is almost always because of a recursive function with a base case that isn't being met.

Viewing the stack

Consider this code...

(function a() {
a();
})();

Here is the stack after a handful of calls...

Web Inspector

As you can see, the call stack grows until it hits a limit: the browser hardcoded stack size or memory exhaustion.

In order to fix it, ensure that your recursive function has a base case which is able to be met...

(function a(x) {
// The following condition
// is the base case.
if ( ! x) {
return;
}
a(--x);
})(10);

Call Stack size in recursive functions: Maximum call stack size is lower than expected

  1. The size of the stack is some number of bytes, not some number of function calls. Every parameter you add to a function call consumes some memory, so less stack available;
  2. See 1 above
  3. The variables in the function called

How do I know what is the size limit for constructing a Set in JavaScript?

The collection containing the items in a Set is called a "List" in the specification, and a limit on the size of a List is not specified.

These sequences may be of any length

Nor is the size of Set lists in particular specified. (1, 2)


  1. Set set.[[SetData]] to a new empty List.

So, it must be implementation-defined.

Is it something that depends on the Browser? Or on the PC running the Browser?

It will depend on the JavaScript engine the browser uses (for example, V8, or SpiderMonkey, or JavaScriptCore, among others).

Is there a way to get that number?

Just .add items to a Set until it throws.

const getSetSizeLimit = () => {
let i = 0;
const set = new Set();
while (true) {
try {
set.add(i);
} catch(e) {
return i;
}
i++;
}
return i;
};
console.log(getSetSizeLimit());

Javascript: Why does the maximum stack size appear to change dynamically?

The stack size depends on multiple things here.

Firstly, when you call a function, all the parameters and a return address are pushed to the stack. Also all local variables that you would define within the function would be on the stack.

Secondly, the stack grows in the opposite direction as the heap. A process uses one memory space for the stack and the heap. If you have variables on the heap (for example if you instantiate a variable with new it will be created on the heap, not on the stack). The more on the heap, the less room there is for the stack to grow into.

I don't know how your setup looks like, but if there is anything else running in your browser-tab than that will interfere with the stack-size as it will take up some space.

I am getting RangeError: Maximum call stack size exceeded error in Javascript

As you wrote yourself, "Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle".

In your implementation, fn calls itself infinitely. In the process, the javascript virtual machine creates a fonction context in memory at each iteration. This can be done up to a certain times after which the error Maximum call stack size exceeded throws.

What I am doing wrong?

You return true when you find a happy number, but you never return false otherwise. Add a condition to detect unhappy numbers (detect a cycle) and return false in that case.

Edit: here is an example implementation:

var isHappy = function(n) {
if(n.length<2) return false

// placeholder to store already called values
const calledValues= new Set()

var fn=(n)=>{
let i=0;
let sum=0;

if (calledValues.has(n))
// cycle detected!
return false;

calledValues.add(n);

while(i<n.length){
sum=sum+Math.pow(n[n.length-1-i],2);
i++;
}

if (sum !== 1)
return fn(sum.toString());
else
// sum === 1, number is happy!
return true
}

// make sure to pass a string to fn
return fn(n.toString());
};

(new Array(20)).fill().map((_,i)=>10+i)
.forEach(n=> console.log(n, "is happy?", isHappy(n)));


Related Topics



Leave a reply



Submit