Chrome allocations profile: why memory consumption for handleEvent is so huge?

To start with one might take a look at this post on regarding ability to assign pojo as an event listener. The thing is that this object should have handleEvent method in order to be able to react on a certain event. For example:

const handler = {handleEvent(e) {this[`on${e.type}`](e)}};

In the above mentioned post on author sends us to benchmark, which was created exactly to demonstrate the fact, that usage of handleEvent basically takes O(1) memory overheads. For example (not the actual benchmark):

const handlersQueue = [];

const masterHandler = {
    handleEvent(e) {
    onclick: function() {++this.counter},
    counter: 0

for (let i = 0; i < 1e4; i++) {
    const newHandler = Object.create(masterHandler);
    document.body.addEventListener('click', newHandler);

document.body.dispatchEvent(new Event('click'));

In that case it is logical to assume, that all the event handlers are going to borrow handleEvent method from a prototype (masterHandler). Author has created a little bit more sophisticated form of above mentioned example (take a look at DynamicHandler class), but overall idea stays the same. On the contrary, allocations profile shows an enormous memory consumption by handleEvent function (Chrome Version 64.0.3282.186 (Official Build) (64-bit), MacOS High Sierra): weird memory consumption results The questions are:

  • a) why this is happening?
  • b) shouldn't usage of handleEvent for all event listeners cost us O(1) (basically SelfSize(bytes) of 0 bytes) and not O(n)?
  • c) is it a sign of an issue either in ChromeDevTools or V8 themselves?

1 answer

  • answered 2018-03-13 20:43 jmrk

    V8 developer here. String concatenation, i.e. 'on' + e.type in the original benchmark, or your template literal based alternative:


    causes (unsurprisingly?) a string to be created on every invocation. 3.3MB for 100,000 invocations is 33 bytes per iteration; the String "onclick" requires 32 bytes on the heap, so that explains most of it.

    While this is not particularly efficient, those strings at least are short-lived, i.e. the garbage collector will get rid of them quickly. Unless you're taking allocation profiles, you probably won't even notice; on the other hand, if you ever end up chasing real memory consumption issues, getting rid of such noise on the profile might be worth it just for that reason.

    If you want to save that overhead, you could simply rename the "onclick" function to "click" (and similar for any other events), so you don't need to muck with strings at all.