Closed Sendouc closed 2 weeks ago
protectedObjectCount
Yes, very much sounds like a memory leak.
As of Bun v1.1.27, the Promise objects do not stay alive and memory usage stabilizes around 512 MB on my mac and is overall is higher than it should be
This is in Bun v1.1.32 (latest):
{
objectTypeCounts: {
Function: 6847,
string: 6755,
Structure: 5575,
UnlinkedFunctionExecutable: 4855,
FunctionExecutable: 4799,
Object: 1546,
JSLexicalEnvironment: 1319,
FunctionCodeBlock: 1055,
GetterSetter: 942,
NativeExecutable: 814,
StructureRareData: 579,
SymbolTable: 550,
UnlinkedFunctionCodeBlock: 535,
Array: 519,
"Immutable Butterfly": 353,
StructureChain: 258,
PropertyTable: 246,
FunctionRareData: 191,
RegExp: 165,
CustomGetterSetter: 124,
Uint8Array: 118,
symbol: 117,
AsyncFunction: 87,
Module: 83,
UnlinkedProgramCodeBlock: 76,
DOMAttributeGetterSetter: 73,
ProgramExecutable: 67,
SparseArrayValueMap: 57,
Set: 45,
InternalPromise: 37,
Map: 29,
JSPropertyNameEnumerator: 28,
JSModuleEnvironment: 14,
JSSourceCode: 14,
ModuleRecord: 14,
JSAsyncGeneratorFunction: 10,
Promise: 10,
WeakMap: 6,
Arguments: 5,
ModuleNamespaceObject: 5,
ScopedArgumentsTable: 5,
ModuleProgramExecutable: 4,
UnlinkedModuleProgramCodeBlock: 4,
GeneratorFunction: 3,
TextEncoder: 3,
ArrayBuffer: 2,
AsyncGeneratorFunction: 2,
BigInt: 2,
BufferList: 2,
Callee: 2,
Crypto: 2,
DebugHTTPServer: 2,
Headers: 2,
Iterator: 2,
MessageChannel: 2,
NodeJSFS: 2,
Performance: 2,
ReadableStreamDefaultController: 2,
ReadableStreamDefaultReader: 2,
ReadableStream: 2,
StringDecoder: 2,
SubtleCrypto: 2,
Timeout: 2,
URLSearchParams: 2,
URL: 2,
AbortSignal: 1,
"Array Iterator": 1,
AsyncFromSyncIterator: 1,
AsyncGenerator: 1,
AsyncIterator: 1,
BigInt64ArrayPrototype: 1,
BigUint64ArrayPrototype: 1,
BlobInternalReadableStreamSource: 1,
Blob: 1,
Boolean: 1,
Buffer: 1,
Bun: 1,
CryptoHasher: 1,
Dirent: 1,
EventEmitter: 1,
EventTarget: 1,
File: 1,
FinalizationRegistry: 1,
Float16ArrayPrototype: 1,
Float32ArrayPrototype: 1,
Float64ArrayPrototype: 1,
Generator: 1,
GlobalObject: 1,
Int16ArrayPrototype: 1,
Int32ArrayPrototype: 1,
Int8ArrayPrototype: 1,
InternalFieldTuple: 1,
InternalModuleRegistry: 1,
InternalPromisePrototype: 1,
Intl: 1,
"Iterator Helper": 1,
JSGlobalLexicalEnvironment: 1,
JSGlobalProxy: 1,
JSON: 1,
"Map Iterator": 1,
Math: 1,
ModuleLoader: 1,
ModulePrototype: 1,
NextT
Number: 1,
ProcessBindingConstants: 1,
Process: 1,
Prototype: 1,
ReadableHTTPResponseSinkController: 1,
Reflect: 1,
"RegExp String Iterator": 1,
Request: 1,
Response: 1,
"Set Iterator": 1,
ShadowRealm: 1,
Stats: 1,
"String Iterator": 1,
String: 1,
Symbol: 1,
TextDecoder: 1,
TextEncoderStreamEncoder: 1,
Uint16ArrayPrototype: 1,
Uint32ArrayPrototype: 1,
Uint8ArrayPrototype: 1,
Uint8ClampedArrayPrototype: 1,
WeakRef: 1,
WeakSet: 1,
WebAssembly: 1,
console: 1,
require: 1,
resolve: 1,
},
protectedObjectTypeCounts: {
UnlinkedProgramCodeBlock: 76,
Function: 16,
UnlinkedModuleProgramCodeBlock: 4,
AsyncFunction: 1,
DebugHTTPServer: 1,
GlobalObject: 1,
Timeout: 1,
},
heapSize: 6781296,
heapCapacity: 9140608,
extraMemorySize: 3516656,
objectCount: 41426,
protectedObjectCount: 100,
globalObjectCount: 1,
protectedGlobalObjectCount: 1,
}
RSS 519
This particular issue is fixed, and I suspect the situation will improve further after #14384 lands
What version of Bun is running?
1.1.25-canary.20+d4237b075
What platform is your computer?
Darwin 23.6.0 arm64 arm
What steps can reproduce the bug?
1) Clone this repo https://github.com/Sendouc/bun-memory-leak-test (default Remix project created via the create-remix CLI with a loader added to the front page route, minimal Bun server and heapStats logging in the entry.server.tsx file) 2)
bun run build
and thenbun run start
3) Generate some load via autocannon:bunx autocannon 'http://localhost:3001/' -d 500
4) Observe the logsWhat is the expected behavior?
protectedObjectTypeCounts.Promise
does not keep going up indefinitelyWhat do you see instead?
protectedObjectTypeCounts.Promise
keeps going up:Additional information
Specifically this seems to be related to loaders. Before I add a loader to the minimal project there is no behavior like this. Further when I inspect the
generateHeapSnapshot()
it seems that the "Promises" list contains a lot of loaders.I've been looking into this after failing to deploy my Bun converted project. It seems that there is a memory leak going which made me revert back to Node.js (in the graph pink is Node.js and others are Bun):
So it seems there is something amiss there but the above is just my hypothesis what it could be related to.