question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Memory management: references not detached

See original GitHub issue

Context

I am using swal2 in a heavy SPA that uses VueJs. I am currently busting all of the potential memory leakages in the application, and I believe I’ve found a potential threat coming from sweetalert2.

Current behavior

This problem occurs when you fire an alert using either a preConfirm or by just attaching a function through .then(), like so:

var baz = 4;
Swal.fire({
  title: 'Test',
  preConfirm: () => this.foo(baz)
}).then((d) => {
  if (d.value) {
    this.bar(baz)
  }
})

It is important to note that this fire method has been called inside a vuejs component, therefore the this context of both foo and bar includes a whole bunch of data/properties/methods that may consumes a lot of memory.

If this swal modal is fired and the user cancel it (e.g. by clicking outside), the swal closes itself and everything works like a charm, except when you move out of the current vuejs component, and take a quick look at a Chrome heap snapshot. Here is what I see :

image

We can clearly see that a WeakMap inside sweetalert is retaining a Promise (I’m using bluebird promises btw, but it also happens without bluebird). This promise seems to have all my vuejs component attached as its context, preventing the GC from collecting the memory.

It is not an actual memory leak because the memory does not stack. It’s just an annoying reference that prevent the GC from collecting the underlying context.

Proposed solution

When going deeper using the debugger, I’ve identified the source of this behavior:

privateMethods and privateProps

  • privateProps.promise is retaining a promise with my vuejs context.
  • privateMethods.swalPromiseResolve seems to retain a vuejs context as well.
  • privateProps.innerParams is retaining my preConfirm and therefore the vuejs context attached to the function.
  • privateProps.domCache is retaining references a DetachedHtmlElement that can be seen in the heap snapshot. (less harmful but still)

Code

Here is my proposed solution : https://github.com/jf-m/sweetalert2/commit/b2a77c6639c8d5f7b18bc24d5a58c85b41bd5218

I have not made any pull-request because I am not sure wether removePopupAndResetState is the right place to dispose of privateProps.innerParams, privateProps.domCache and privateMethods.swalPromiseResolve

However, I’ve tried my commit and the GC collects my vue components, is seems to work in my test case.

By the way, thank you for this amazing project, it’s saving me a huge amount of time in all my projects 😉 !

Cheers 🍺

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
gvernicommented, May 3, 2019

@limonte thanks for the PR! While trying to reproduce this, I was doing some other profiling and I could see that in some cases there are some detached DOM elements left by Swal (about 60 of them). I’ll double check with this PR as well and if my investigations confirm that I’ll open a new issue.

1reaction
gvernicommented, May 2, 2019

Thanks you so much @jf-m for the hard work! Sorry if I didn’t get to look at your changes yet, but I was a bit busy. I’ll try to review them as soon as possible!

Read more comments on GitHub >

github_iconTop Results From Across the Web

What are the effects of not detaching a Shared Memory Segment
Not detaching will prevent others from deleting the memory segment, this is true on windows and on linux. Thus you will have a...
Read more >
Overview of JNI object references - IBM
Global references are not automatically deleted, so the programmer must handle the memory management. Every global reference establishes a root for the ...
Read more >
Causes of Memory Leaks in JavaScript and How to Avoid Them
Insufficient care about memory management generally doesn't produce dramatic consequences when it comes to "old-fashioned" web pages.
Read more >
4 Types of Memory Leaks in JavaScript and How to Get Rid Of ...
The main cause for leaks in garbage collected languages are unwanted references. To understand what unwanted references are, first we need to ...
Read more >
Debug memory leaks with the Microsoft Edge Detached ...
A DOM memory leak occurs when an application keeps references to more and more of these detached elements, without actually reusing them ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found