Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory on acceptance tests on ember 1.13.10+ #12618

Closed
calderas opened this issue Nov 16, 2015 · 17 comments · Fixed by #12666
Closed

Memory on acceptance tests on ember 1.13.10+ #12618

calderas opened this issue Nov 16, 2015 · 17 comments · Fixed by #12666

Comments

@calderas
Copy link

test repo: https://github.com/calderas/leaky-mcleakerson

After upgrading our app to ember 1.13 chrome crashes when running Acceptance Tests

V8 error: Allocation failed - process out of memory (CALL_AND_RETRY_LAST).  Current memory usage: 1949 MB

Following the same approach as #11748 I ran some tests on a simple app to compare different versions of ember

Observations:

  • Memory drops when running unit tests on ember 1.12.
  • Memory allocated for tests is ~ twice on ember 1.13 & 2.1 for same app.
  • Memory allocation tends to increase overtime on acceptance tests.

Questions:

  • Is this expected ?
  • Thoughts on how to debug further ?

Memory comparison

screen shot 2015-11-16 at 12 59 31 pm
screen shot 2015-11-16 at 12 58 20 pm
screen shot 2015-11-16 at 12 58 49 pm

Looking at the timeline seems like event listeners remain after tests have completed and detached elements show up on heap profiles.

ef067318-892c-11e5-8a4d-fe75297533cb

f09d0494-892c-11e5-8c0f-aba694f2b135

test repo: https://github.com/calderas/leaky-mcleakerson

@jcope2013
Copy link
Contributor

this one seems related also #12490 and I have been having similar issues with my app

@stefanpenner stefanpenner self-assigned this Nov 16, 2015
@lmcardle
Copy link

I've also been struggling with this on 1.13.10. No idea if this would be helpful, but here is my timeline and heap profile.
memory profile
memory timeline

@stefanpenner
Copy link
Member

@lmcardle it is unfortunately not at all helpful, the only thing that is valuable is actual examples demonstrating leaks.

@stefanpenner
Copy link
Member

Thoughts on how to debug further ?

yes, heap snapshot, find the retainers and address them.

@stefanpenner
Copy link
Member

I took a look, although there may be more leaks. I believe I found a v8 bug. It appears to be leaking due to an inlined function preserving its context...

After some digging, I found:

screen shot 2015-11-26 at 12 08 50 am

Which seems to indicate the normalize function (which doesn't close over anything) via its compiled code and related deopt info, is retaining the resolver.

The following stack appears inlined (causing the grief).

  1. resolve.normalize
  2. this.registry.normalizeFullName = this.applicationRegistry.normalizeFullName;
  3. Registry.prototypr.normalize

I then pinged @mraleph on twitter, who recommended i disabling inlining and try again.

/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --js-flags="--nouse_inlining" --user-data-dir=/tmp/foobar

Manually preventing this specific set of functions from inlining also prevents the leak. hacky patch

And the container leak I noticed went away...

cc @dgeb

@stefanpenner
Copy link
Member

FYI: when searching for memory leaks, having examples that create excessive noise only creates distractions and make finding the source of the leak more difficult.

The key is finding the minimal setup required to cause a leak, basically deleting parts of the example until the leak stops, and following that process until only a concise example remain.

After deleting nearly everything the leak was still obvious, and made for a much easier time debugging. Ultimate the leak appears to be a v8 bug, but several work-arounds are possible. With one of those work-arounds, full re-instating the provided tests also no longer leak containers.

dgeb added a commit to dgeb/ember.js that referenced this issue Dec 1, 2015
…ry / resolver access.

This fix changes the expectations of Registry to accept a `resolver`
that’s an object with a `resolve` method instead of a straight function.

This allows us to avoid closing over access to a resolver object inside
a function. It also allows us to avoid setting functions which shadow
prototype functions unnecessarily.

Setting `Registry#resolver` to a function is still allowed through a
constructor option. The `resolver` function will be converted into
an object with a `resolve` method and will result in a single deprecation
warning.

This fix also eliminates the need for application instances to override
their registry’s `normalizeFullName` and `makeToString` methods.
Instead, the fallback registry will be checked when evaluating these
methods before returning the defaults. Again, this avoids the need to
override instance functions that shadow prototype functions.

[Fixes emberjs#12618]
@rwjblue rwjblue reopened this Dec 2, 2015
@rwjblue
Copy link
Member

rwjblue commented Dec 2, 2015

This should have been addressed by #12666, but I'm reopening so that we can confirm.

@shen6653
Copy link

shen6653 commented Dec 3, 2015

Is this fix available for 1.13?

rwjblue pushed a commit that referenced this issue Dec 4, 2015
…ry / resolver access.

This fix changes the expectations of Registry to accept a `resolver`
that’s an object with a `resolve` method instead of a straight function.

This allows us to avoid closing over access to a resolver object inside
a function. It also allows us to avoid setting functions which shadow
prototype functions unnecessarily.

Setting `Registry#resolver` to a function is still allowed through a
constructor option. The `resolver` function will be converted into
an object with a `resolve` method and will result in a single deprecation
warning.

This fix also eliminates the need for application instances to override
their registry’s `normalizeFullName` and `makeToString` methods.
Instead, the fallback registry will be checked when evaluating these
methods before returning the defaults. Again, this avoids the need to
override instance functions that shadow prototype functions.

[Fixes #12618]

(cherry picked from commit 529bfc3)
@stefanpenner
Copy link
Member

Is this fix available for 1.13?

@shen6653 I don't know if it has been backported, we would likely accept a PR doing so.

@mixonic
Copy link
Member

mixonic commented Mar 27, 2016

It seems like this just needs confirmation against the testing repo provided in the original ticket.

@oso-mate
Copy link

Forked the original leaker repo and upgraded to Ember 2.3.2. The memory leak issue seems to have been fixed for this version as part of: #12666

Performant tests timeline (2.3.2)
screen shot 2016-03-28 at 12 23 58 pm
Notice even listeners seem to be properly handled.

Original tests timeline (1.13.10)
screen shot 2016-03-28 at 2 50 53 pm

@stefanpenner
Copy link
Member

The memory leak issue seems to have been fixed for this version as part of: #12666

to be pedantic, we are working around a v8 bug in that PR :trollface:

@calderas
Copy link
Author

I just tested this again with the latest ember/ember-cli and looks so much better !!!
https://github.com/calderas/leaky-mcleakerson/tree/feature/ember-2.4.3

Memory doesn't increase between acceptance tests anymore
screen shot 2016-03-28 at 6 27 29 pm

Thanks for the constant improvements !

@acorncom
Copy link
Contributor

Per comments above, it looks like this there have been improvements. I'll close this for now, but please comment if we should re-open it.

@micky2be
Copy link

I would love to see a fix done for 1.13.x

I'm currently updating an app (quit big) from 1.12.2 to 2.x, and passing by 1.13 to fix all deprecation warning is a most.
So if we cannot run the tests of our app, it's gonna be very hard to know if any refactoring has been done correctly.

@e00dan
Copy link
Contributor

e00dan commented Aug 23, 2017

Is there any way to manually clear memory between acceptance tests run? I'm also interested in this. I doubt any fix will be backported to 1.13 and it's better to upgrade to Ember 2, but maybe there's some workaround?

@micky2be
Copy link

@kuzirashi You could do like me.
I run multiple group of tests one by one with different filter.
It reloads PhantomJS, with fresh memory.
I've been surprise that by doing that it was faster than keeping the same instance of PahntomJS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet