-
-
Notifications
You must be signed in to change notification settings - Fork 5k
router.push memory leak #3054
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
Comments
I seem to have found another very similar memory leak, but this one affects even the <router-link>. Here is the source code for this memory leak: https://github.com/ChuckFields/VueRouterLingeringObject2 For this one, the 'LingeringObject' has children ('LingeringChild'). The store has a getter 'lingeringObjChildren' to get these children. In the About.vue we watch for the lingeringObj to change. In the watcher, if we just reference getters.lingeringObjChildren, we now have a memory leak, and going back to the Home page will result in the LingeringChild to remain in memory. |
I don't see any leak with the first example: memory stays stable When reporting a memory leak, as said in the other issue, please keep it minimal, if the second one is related to watch, then don't add a router and store. Also, if it's on an HTML file (you can share just the content) it's much easier to check for us and play around locally |
@posva This is NOT an accumulating memory leak, in other words, doing the steps to reproduce this multiple times will not result in multiple objects remaining in memory. However it is still a memory leak. The LingeringObject should not be in memory at all when going back to the home page, but it is. Nothing in the code I've written maintains a reference to that object. This is a very scaled back example of a large enterprise application in which the object that remains in memory is very large ~500mb. For these examples, I couldn't find a way to reproduce these issues without using the router and store. The second example is related to the watch, but it watches a value in the store, and needs the router-link to reproduce. I'm not sure what I could have done to minimize these examples. I created repositories with the full source code so you can run it locally and see the memory leak in action. |
@posva, I've found a workaround:
By wrapping the next() call with a nextTick in beforeRouteLeave, we fix the issue for both router.push and router-link. I do still think there is a real bug here, and I think this workaround can give some clues as to what exactly might be causing this. If I have time, I will investigate further. |
@ChuckFields Thank you for this workaround. I have been looking at this issue off and on for a few months. Inspecting the memory allocation, I was seeing the Component memory release then almost instantly re-inflate during navigation to a new component and lots of Detached Elements. Your workaround has resolved this for now. I don't know if it's significant, but I use BootstrapVue |
Version
3.1.3
Reproduction link
https://chuckfields.github.io/
Steps to reproduce
Note: this is a separate memory leak from the one I posted the other day, but has a very similar reproduction setup.
Clicking on the about tab (router link) will create a javascript object with the class 'LingeringObject' and put it in the store under lingeringObj. Clicking on the home tab (router link) destroys the about component and resets lingeringObj to null- this causes the LingeringObject to get removed by the garbage collector- this is all fine, and can be tested by taking a heap snapshots in chrome. Now, the memory leak that I've noticed happens when you use the 'Go Home' button on the about tab. This uses router.push() instead of a <router-link>. After clicking the Go Home button, if you take a snapshot, you'll notice the LingeringObject is still in memory. What's even weirder is when you inspect the object to see what is still holding onto a reference of it- it's showing HTMLButtonElement, which is the Go Home button. Very peculiar. According to the vue router documentation: "...clicking <router-link :to="..."> is the equivalent of calling router.push(...)."
Here is the source code for the reproduction link:
https://github.com/ChuckFields/VueRouterLingeringObject
What is expected?
The LingeringObject to get removed from memory when using router.push()
What is actually happening?
It's staying in memory
The text was updated successfully, but these errors were encountered: