Skip to content

FinalizationGroup in combination with buffers seems to allocate memory without releasing it #30853

Closed
@puzpuzpuz

Description

@puzpuzpuz

Recently I was working on an experimental Buffer pool implementation based on FinalizationGroup API (see #30683) and encountered a weirdness that I'd like clarify. It seems that node doesn't free memory when FinalizationGroup is used to track Buffers (as "holdings") under certain conditions. This issue may be related with off-heap memory allocator or OS memory behavior, but I'd like to confirm that.

Here is the most simple reproducer that I could find:

'use strict';

const fg = new FinalizationGroup(finalizer);

// 8 ticks, 1GB per each => 8GB total
const ticks = 8;
const bufsPerTick = 1024;
const size = 1024 * 1024;

let slices = [];
let tick = 0;
setInterval(() => {
  tick += 1;
  if (tick === ticks) console.log('Registered all slices');
  if (tick > ticks) {
    slices = [];
    return;
  }

  slices = [];
  for (let i = 0; i < bufsPerTick; i++) {
    const buf = Buffer.alloc(size);
    const slice = buf.slice();
    slices.push(slice);
    fg.register(slice, buf);
  }
}, 500);

let finalized = 0;
function finalizer(iter) {
  for (const _ of iter) {
    finalized += 1;
    if (finalized === ticks * bufsPerTick)
      console.log('All finalizer callbacks are triggered');
  }
}

When this script is run under --harmony-weak-refs flag, node process consumes about 2GB of physical memory on my machine (and about 2.5GB of virtual memory) and that value doesn't decrease even after 10 minutes.

On the other hand, if you comment the fg.register(slice, buf); line, you'll see that resident memory consumption eventually goes down to ~32KB (virtual is ~600MB).

Once again, I'm not sure if that's a bug, but I'd like to understand the reason of such behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    memoryIssues and PRs related to the memory management or memory footprint.v8 engineIssues and PRs related to the V8 dependency.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions