ember-best-practices / memory-leak-examples

Examples of memory leaks and common patterns that cause them
223 stars 16 forks source link

Expand on "fuzzy" part of Heap Snapshot #14

Closed hoIIer closed 2 years ago

hoIIer commented 6 years ago

Hey so I just discovered this and upon doing a heap snapshot of an integration test for a very simple component that uses the new style of tests, I discovered that it has 4 references to Container. When I open up a single one of those, I am quickly lost and have no idea what to look for. Some of the nodes in the graph expand to a huge number of objects that are deep within some part of the code.

image

How can I learn more about how to identify what to look for or find out why a reference to a container is being kept and make use of this? What are the ramifications of 4 references?

Here is the component for the integration test:

import Component from '@ember/component';

const UIIsLoadingComponent = Component.extend({
  classNames: ['is-loading'],
  classNameBindings: [
    'isLoading:is-loading--visible',
    'isLastPage:is-loading--is-end',
  ],
});

UIIsLoadingComponent.reopenClass({
  positionalParams: ['name', 'isLoading', 'isLastPage'],
});

export default UIIsLoadingComponent;

Here is the top 1/3 of the integration test file (cut out the other 2 tests):

import { module, test } from 'qunit';
import hbs from 'htmlbars-inline-precompile';
import { render } from '@ember/test-helpers';
import { setupRenderingTest } from 'ember-qunit';

module('Integration | Component | ui/is-loading', (hooks) => {
  setupRenderingTest(hooks);

  hooks.beforeEach(function() {
    this.set('isLastPage', false);
  });

  test('it renders', async function(assert) {
    assert.expect(4);

    await render(hbs`{{ui/is-loading isLastPage=isLastPage}}`);

    const text = '[data-test-is-loading-text]';

    assert.dom(text).exists();
    assert.dom(text).hasText('loading more...');

    this.set('isLastPage', true);

    assert.dom(text).hasText('no more results');

    // Template block usage:
    await render(hbs`
      {{#ui/is-loading}}
        template block text
      {{/ui/is-loading}}
    `);

    assert.equal(this.element.textContent.trim(), 'template block text');
  });

PS I just added 3 acceptance tests to our app that previously had none and our ci server exploded when the max of 3GB memory was hit during build of the ember app... when I do the same process described in example 1 of this repo applied to ember t -f acceptance -s, I get 7 references to Container:

image

I don't know enough to diagnose but this is worrying me as this repo already stated even 1 reference is bad.

crixx commented 6 years ago

I agree! I would also be happy to have more details on the exact approach when dealing with the new test style. If possible also with a current Chrome Dev Tools version. Would really appreciate that!

@erichonkanen how did you finally manage to find the leak?