Skip to content

high memory usage when too much timers resolved in the same tick #1177

@CyanChanges

Description

@CyanChanges
// ported from Bun: 
// https://github.com/oven-sh/bun/blob/c82e4fb485808a7582c227c1eb4dd8cc25ad7b86/bench/snippets/set-timeout.mjs#L10
const ops = Deno.core.ops;

let count = 20_000_000;
const batchSize = 1_000_000;

const beginTime = Temporal.Now.instant()
ops.op_print("Run\n");

let { promise, resolve, reject } = Promise.withResolvers();
let remaining = count;

if (batchSize === 0) {
  for (let i = 0; i < count; i++) {
    setTimeout(() => {
      remaining--;
      if (remaining === 0) {
        resolve();
      }
    }, 0);
  }
  await promise;
} else {
  for (let i = 0; i < count; i += batchSize) {
    let batch = Math.min(batchSize, count - i);
    const bbt = Temporal.Now.instant()
    ops.op_print(`Batch ${i} - ${i + batch}`);
    let { promise: batchPromise, resolve: batchResolve } = Promise.withResolvers();
    let remaining = batch;
    for (let j = 0; j < batch; j++) {
      setTimeout(() => {
        remaining--;
        if (remaining === 0) {
          batchResolve();
        }
      }, 0);
    }
    await batchPromise;
    const bet = Temporal.Now.instant()
    ops.op_print(`: ${bet.since(bbt).toLocaleString("en-US")}\n`);
  }
}

const fmt = new Intl.NumberFormat();
ops.op_print(`Executed ${fmt.format(count)} timers\n`);
const endTime = Temporal.Now.instant();
ops.op_print(`Duration: ${endTime.since(beginTime).toLocaleString("en-US")}\n`)

Deno is taking a maximum of 864MB memory:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions