npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ember-cli-memory-leak-detector

v0.7.1

Published

Automatic memory leak detection for ember apps

Downloads

12,178

Readme

Node.js CI Ember Observer Score npm version

ember-cli-memory-leak-detector

An ember-cli addon that captures and analyzes a heap snapshot after your tests have finished running in Chrome, in order to detect memory leaks. If any of your app's classes are retained in the heap, your tests will fail.

Compatibility

  • Ember.js v3.16 or above
  • Ember CLI v2.13 or above
  • Node.js v10 or above

Installation

ember install ember-cli-memory-leak-detector

Update testem.js to use a --remote-debugging-port=9222. 9222 is the recommended default, but this port can be configured. You can not use ember-cli's default of 0

// testem.js
browser_args: {
  Chrome: {
    dev: ["--remote-debugging-port=9222"],
    ci: ["--remote-debugging-port=9222"]
  },
},

Usage

Whenever you run your tests in Chrome via Testem (via ember test or ember test --server), this addon will capture a heap snapshot after the tests complete and search the heap snapshot for any of your app or addon's ES classes. If any of your app or addon's classes are retained in heap snapshot (indicating a memory leak) your test suite will fail and a report of the retained class names will be logged.

CI

When run in CI (via ember test/ember exam), this addon will ensure that your tests fail if a memory leak is introduced by a commit or PR.

A note about production and ci environments

It may be desirable to run memory leak detection on a production build of the app using ember test --environment=production. Production builds normally mangle class names, which breaks our ability to detect memory leaks, so this needs to be disabled.

//ember-cli-build.js

'ember-cli-terser': {
  terser: {
    compress: { keep_classnames: true },
    mangle: { keep_classnames: true }
  }
}

Production and CI environments also (by default) add IE11 as a compile target, which will result in classes being transpiled away, so we need to remove this as well.

//config/targets.js

'use strict';

const browsers = [
  'last 1 Chrome versions',
  'last 1 Firefox versions',
  'last 1 Safari versions'
];

// const isCI = Boolean(process.env.CI);
// const isProduction = process.env.EMBER_ENV === 'production';

// if (isCI || isProduction) {
//   browsers.push('ie 11');
// }

module.exports = {
  browsers
};

Both of these changes can be optionally implemented using ENV variables to ensure we are only making these changes when we want to run memory leak detection.

Dev

When run during development, (via ember test --server) memory leaks can be detected after running individual tests or modules via the QUnit UI's filter input or module select. This enables a TDD-like experience for fixing memory leaks.

Note: Memory leak detection currently relies on Testem and Chrome's remote debugging API, so it is not possible to detect memory leaks when running ember server and then visiting localhost:4200/tests in browser.

The effectiveness of this addon is dependent on:

  1. The coverage of your test suite. If leaky code exists in your app but is not exercised by your tests then this add-on can not detect that leaky code.
  2. Your usage of ES classes. This addon functions by getting a list of ES classes in your app/addon code and looking for those objects in the heap snapshot. The addon can only detect leaked objects that have a class name defined in your code.

Configuration

// config/environment.js

'ember-cli-memory-leak-detector': {
  enabled: process.env.DETECT_MEMORY_LEAKS || false,
  failTests: false,
  ignoreClasses: ['ExpectedLeakyClass'],
  remoteDebuggingPort: '9222',
  timeout: 90000,
  writeSnapshot: true
}
  1. enabled (default true) Set to false to disables memory leak detection. Consider using an environment variable (process.env.DETECT_MEMORY_LEAKS) to control when memory leak detection is run.

  2. failTests: (default true) By default when a leak is detected we add a failed test. Set this to false to prevent memory leaks from causing your tests to fail, and instead log a console warning.

  3. ignoreClasses: (default []) By default, the addon will discover all class names in your app and throw a test error if it detects any of them in the heap snapshot. Use this option to ignore specific classes that you expect to leak or plan to fix later. If any of these ignored classes are leaked they will be output as a warning in the test output. Note: framework-level classes such as App are ignored to avoid false positives.

  4. remoteDebuggingPort: (default 9222) Configures which port to connect to the testem Chrome instance. This value must match the --remote-debugging-port flag set in your app's testem.js

  5. timeout: (number, default null) Configures the length of time, in milliseconds, to wait for the memory leak detection test to complete. This value will override any existing timeouts in your test framework. For example, QUnit has a default test timeout of 60s. If you expect memory leak detection to take longer than this it may be useful to specify a longer timeout for the memory leak detection test. Note: Currently this timeout is only used with QUnit

  6. writeSnapshot: (default false) Set this to true to write the heapsnapshot to disk as Heap.heapsnapshot. This is helpful for fixing memory leaks, since the file can be uploaded into Chrome DevTool's Memory panel for analysis.

Fixing memory leaks

Once this addon has helped you identify that your app or addon is leaking memory you can begin the process of fixing those memory leaks.

Fixing memory leaks requires an understanding of how to find leaky application code in a heap snapshot, and an understanding of what code patterns cause memory leaks and how they can be refactored to prevent leaks. Teaching these things is outside the scope of this addon's documentation (for now, contributions welcome!) but there are some existing resources that can help you here.

  1. https://developers.google.com/web/tools/chrome-devtools/memory-problems is a great introduction to memory problems in the browser and the memory tools available in Chrome DevTools.

  2. https://github.com/ember-best-practices/memory-leak-examples is a fantastic free ember-centric resource for learning about patterns that cause memory leaks, how to identify leaky code, and how to fix those leaks.

  3. https://embermap.com/topics/memory-leaks Another ember-centric resource for learning about memory leaks in the context.

Most of these resources involve running some code/tests and manually capturing and analyzing a heap snapshot in Chrome DevTools. You may find that this addon paired with the writeSnapshot config option and ember test's filter flag provide a handy way to speed up those manual processes.

Dealing with large heap snapshots

Depending on the size of your app and the number of memory leaks it has you may find that the size of your heap snapshot causes problems during your test runs.

  1. Consider setting the enabled config to an environment variable for more control over when memory leak detection is run, for example to only run in CI.
'ember-cli-memory-leak-detector': {
  enabled: process.env.DETECT_MEMORY_LEAKS || false,
}
$ DETECT_MEMORY_LEAKS=true ember test
  1. Allocate extra memory to node

You may find that node's default memory allocation of 512Mb is insufficient for analyzing your app's heap snapshot. In this case you may need to allocate extra memory to node, otherwise node will run out of memory and your test run will crash.

Use the max_old_space_size flag to allocate extra memory. The following example increases node's memory to 8Gb.

node --max_old_space_size=8192 node_modules/.bin/ember test

Additionally, if you are running memory leak detection in a CI environment, you may need to increase the size of your CI resource.

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.