asyncly/EventEmitter2 — pull request #135 by AVVS (2014-12-12 03:26:17+00:00)
Title: GC on both .off and .removeAllListeners

Perform gc collection on both .off and .removeAllListeners,
extract `recursivelyGarbageCollect`, add `makeShallowCopy` for cleaning
lost of `null` properties, add gc invocation counters `this._gc`.

GC can be controlled via env vars `GC_KEY_THRESHOLD`, defaults to 10000.
Which means that a shallow copy of object will be created if it grows over
that amount of `null` properties.

`GC_FREQUENCY` controls how many calls to `recursivelyGarbageCollect` must be
made before we actually do the GC. Defaults to 50000

Addition to #65, #132

Would love your comments. With default settings in my projects usual GC run takes from 150 to 250ms, which is, admittedly, not much granted how much it cleanses (ie, in an hour without that fix heap grows to 1GB).

What I haven't explored is using `.delete` instead of making shallow copies of an object and how it really affects performance here.
Ideas taken from this talk: https://www.youtube.com/watch?v=ip9LGtNsxZA