Description
Tested in NodeJS Versions: v22.3.0, v20.14.0, v18.20.3, v16.20.2
It appears as though Buffer/Uint8Array consumes much more memory than I would expect. This is particularly obvious with many small instances.
For example:
const data = new Uint8Array(12)
<-- I would think this would consume ~12bytes
It appears to have a shallow size of 96bytes and retains 196bytes
I'm not sure if this is a V8 issue but when I try the same in Chrome 126 I see a similar issue but it uses slightly less memory

Why this is an issue
I stumbled on this while trying to profile memory issues while pulling large amounts of MongoDB documents into memory, even projecting the documents to just return 2 ObjectIds each (we're building potentially large graphs in memory from the links).
A BSON ObjectId is 12 bytes. So we estimated ~24MB per million edges. (maybe a bit more for object overhead etc)
In reality this uses almost 500MB
At first I thought this was an issue with BSON's implementation but this can be recreated using Uint8Array directly.
Try it out
const arr = []
const heapBefore = process.memoryUsage().heapUsed
for (let i = 0; i < 2000000; i++) {
arr.push(new Uint8Array(12)) // Same with Buffer.alloc(12)
}
const heapAfter = process.memoryUsage().heapUsed // Not super accurate but illustrates the issue
const size = Math.round((heapAfter - heapBefore) / 1024 / 1024)
console.log(`Used ${size}MB to store ${arr.length} Uint8Array(12)`)
// Used 473MB to store 2000000 Uint8Array(12)
It doesn't appear that the memory used increases much with the size of the Uint8Array. Doubling the size of each Uint8Array from 12 -> 24 only increases the memory usage to 485MB in the above test. This tells me there's probably some overhead in the data structure itself than some data being duplicated or something.
Curiously, when I try the same thing with Buffer.from(new Uint8Array(12))
it only outputs ~240MB. I assume this is because buffer doesn't keep a reference to something(?) and GC happens sometime before capturing heapUsed.
See below when using Buffer.from(new Uint8Array(12)) it retains 100bytes less 🤔
Thanks
Big thanks to the Node.js Performance Team in advance. You're doing amazing work 👍 Please let me know if this is an issue with V8 directly or if this is completely expected behaviour. It really caught me off guard.