momocow / node-cq-websocket

A Node SDK for developing QQ chatbots based on WebSocket, which is depending on CoolQ and CQHTTP API plugin.

Home Page:https://cq-websocket.js.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Memory leak in EventBus

momocow opened this issue · comments

For test snippets, see performance/leakage/once.test.js.

Within the test for CQWebSocket#once(), memory grows about 342KB after 180 iterations.

[node-cq-websocket] # npm run perf

> cq-websocket@2.0.0 perf /workspace
> tape performance/**/*.test.js

TAP version 13
# EventEmitter#once()
ok 1 should be equivalent
# CQWebSocket#once()

/workspace/node_modules/leakage/lib/index.js:66
    throw heapError
    ^
MemoryLeakError: Heap grew on 6 subsequent garbage collections (180 of 180 iterations) by 342 kB.

  Iterations between GCs: 30

  Final GC details:
  [   25.7 kB] [+ 181x] [-   1x] Array
  [   7.68 kB] [+ 120x] [-   0x] system / Context
  [   6.48 kB] [+  90x] [-   0x] Closure
  [   5.28 kB] [+  60x] [-   0x] Promise
  ... (5 more)

    at testConstantHeapSize (/workspace/node_modules/leakage/lib/testConstantHeapSize.js:24:12)
    at iterate (/workspace/node_modules/leakage/lib/index.js:64:21)
    at Test.<anonymous> (/workspace/performance/leak.test.js:23:3)
    at Test.bound [as _cb] (/workspace/node_modules/tape/lib/test.js:77:32)
    at Test.run (/workspace/node_modules/tape/lib/test.js:96:10)
    at Test.bound [as run] (/workspace/node_modules/tape/lib/test.js:77:32)
    at Immediate.next [as _onImmediate] (/workspace/node_modules/tape/lib/results.js:75:19)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)

See performance/leakage/on-off.test.js.

Also the leakage occurs on CQWebSocket#on(), CQWebSocket#off(), memory grows about 305KB after 180 iterations..

[node-cq-websocket] # npm run perf

> cq-websocket@2.0.0 perf /workspace
> tape performance/**/*.test.js

TAP version 13
# EventEmitter#on(), EventEmitter#removeAllListener()
ok 1 should be equivalent
# CQWebSocket#on(), CQWebSocket#off()

/workspace/node_modules/leakage/lib/index.js:66
    throw heapError
    ^
MemoryLeakError: Heap grew on 6 subsequent garbage collections (180 of 180 iterations) by 305 kB.

  Iterations between GCs: 30

  Final GC details:
  [   21.6 kB] [+ 180x] [-   0x] Array
  [   5.28 kB] [+  60x] [-   0x] Promise
  [   5.28 kB] [+  90x] [-   0x] system / Context
  [   4.32 kB] [+  60x] [-   0x] Closure
  ... (5 more)

    at testConstantHeapSize (/workspace/node_modules/leakage/lib/testConstantHeapSize.js:24:12)
    at iterate (/workspace/node_modules/leakage/lib/index.js:64:21)
    at Test.<anonymous> (/workspace/performance/leakage/on-off.test.js:24:3)
    at Test.bound [as _cb] (/workspace/node_modules/tape/lib/test.js:77:32)
    at Test.run (/workspace/node_modules/tape/lib/test.js:96:10)
    at Test.bound [as run] (/workspace/node_modules/tape/lib/test.js:77:32)
    at Immediate.next [as _onImmediate] (/workspace/node_modules/tape/lib/results.js:75:19)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)

The test files does not handle the returned promise well when calling bot.emit() resulting in misreporting the leakage.
There is actually no problem with the v2 codebase!

$ npm run perf

> cq-websocket@2.0.0 perf /wsp
> tape performance/**/*.test.js

TAP version 13
# EventEmitter#on(), EventEmitter#removeAllListener()
ok 1 should be equivalent
# CQWebSocket#on(), CQWebSocket#off()
ok 2 should be equivalent
# EventEmitter#once()
ok 3 should be equivalent
# CQWebSocket#once()
ok 4 should be equivalent

1..4
# tests 4
# pass  4

# ok