Version
14.17.5
Platform
All
Subsystem
No response
What steps will reproduce the bug?
See https://github.com/Brooooooklyn/node-ref-object-leak for detail
I have a js function in native side, which accept a JsBuffer:
#[js_function(1)]fnref_buffer(ctx: napi::CallContext) -> napi::Result<napi::JsNumber>{let buffer = ctx.get::<napi::JsBuffer>(0)?;let ref_buffer = buffer.into_ref()?;let ref_count = ref_buffer.unref(ctx.env.clone())?;
ctx.env.create_uint32(ref_count)}The napi_create_reference, napi_reference_unref and napi_delete_reference are called in this function.
In the JavaScript side:
const{ readFileSync }=require('fs')const{ refBuffer }=require('./index.node')const{ displayMemoryUsageFromNode }=require('./util')constBigBuffer=readFileSync('yarn.lock')constinitial=process.memoryUsage()asyncfunctionmain(){for(const[i]ofArray.from({length: 10000000}).entries()){letrefCount=refBuffer(BigBuffer)if(refCount){thrownewError(`refCount should be 0, but got ${refCount}`)}if(i%1000000===0){awaitsleep()// Async function to give GC a chanceif(typeofglobal.gc==='function'){global.gc()}displayMemoryUsageFromNode(initial)}}}functionsleep(){returnnewPromise((resolve)=>{setTimeout(resolve,1000)})}main()We can see the memory is growing:
╔══════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟──────────┼───────────┼──────────┼──────────┼──────────────╢
║ +80.1 MB │ +80 MB │ +80 MB │ +40 B │ 0 B ║
╚══════════╧═══════════╧══════════╧══════════╧══════════════╝
╔═════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟─────────┼───────────┼──────────┼──────────┼──────────────╢
║ +250 MB │ +85.3 MB │ +79 MB │ -170 kB │ -162 kB ║
╚═════════╧═══════════╧══════════╧══════════╧══════════════╝
╔═════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟─────────┼───────────┼──────────┼──────────┼──────────────╢
║ +414 MB │ +85.3 MB │ +79.7 MB │ -170 kB │ -162 kB ║
╚═════════╧═══════════╧══════════╧══════════╧══════════════╝
╔═════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟─────────┼───────────┼──────────┼──────────┼──────────────╢
║ +576 MB │ +85.3 MB │ +79.3 MB │ -170 kB │ -162 kB ║
╚═════════╧═══════════╧══════════╧══════════╧══════════════╝
╔═════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟─────────┼───────────┼──────────┼──────────┼──────────────╢
║ +739 MB │ +85.3 MB │ +79.1 MB │ -170 kB │ -162 kB ║
╚═════════╧═══════════╧══════════╧══════════╧══════════════╝
╔═════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟─────────┼───────────┼──────────┼──────────┼──────────────╢
║ +902 MB │ +85.3 MB │ +79 MB │ -170 kB │ -162 kB ║
╚═════════╧═══════════╧══════════╧══════════╧══════════════╝
╔══════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟──────────┼───────────┼──────────┼──────────┼──────────────╢
║ +1.06 GB │ +85.3 MB │ +79 MB │ -170 kB │ -162 kB ║
╚══════════╧═══════════╧══════════╧══════════╧══════════════╝
╔══════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟──────────┼───────────┼──────────┼──────────┼──────────────╢
║ +1.23 GB │ +85.3 MB │ +79.1 MB │ -170 kB │ -162 kB ║
╚══════════╧═══════════╧══════════╧══════════╧══════════════╝
╔══════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟──────────┼───────────┼──────────┼──────────┼──────────────╢
║ +1.39 GB │ +85.3 MB │ +79 MB │ -170 kB │ -162 kB ║
╚══════════╧═══════════╧══════════╧══════════╧══════════════╝
╔══════════╤═══════════╤══════════╤══════════╤══════════════╗
║ rss │ heapTotal │ heapUsed │ external │ arrayBuffers ║
╟──────────┼───────────┼──────────┼──────────┼──────────────╢
║ +1.55 GB │ +85.3 MB │ +79 MB │ -170 kB │ -162 kB ║
╚══════════╧═══════════╧══════════╧══════════╧══════════════╝
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
Buffer is deallocated
What do you see instead?
Buffer is never been deallocated
Additional information
Brooooooklyn/snappy#25
Version
14.17.5
Platform
All
Subsystem
No response
What steps will reproduce the bug?
See https://github.com/Brooooooklyn/node-ref-object-leak for detail
I have a js function in native side, which accept a
JsBuffer:The
napi_create_reference,napi_reference_unrefandnapi_delete_referenceare called in this function.In the JavaScript side:
We can see the memory is growing:
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
Buffer is deallocated
What do you see instead?
Buffer is never been deallocated
Additional information
Brooooooklyn/snappy#25