vue
vue copied to clipboard
vue2.7 keep-alive removed component no memory free
Version
2.7.12
Reproduction link
Steps to reproduce
- npm install
- npm run serve
- Open the browser and input the http://localhost:8080/
- Click the add button to create a1-component.
- Click the add button to create a2-component.
- Click the add button to create a3-component.
- Click the add button to create a4-component .
- Click the a4-component delete button to remove a4-component
What is expected?
click the a4-component delete button ,I expected the usedJSHeapSize total is 250mb,but it didn't happen.
What is actually happening?
the usedJSHeapSize total still is about 330mb.
When you click the add button ,the usedJSHeapSize will increase about 80mb. click four times ,the usedJSHeapSize total is about 330mb. next click the a4-component delete button ,the usedJSHeapSize Should be reduce 80mb,expected is about 250mb. but usedJSHeapSize total still is about 330mb. you can view operating_steps.gif Steps to reproduce and view memory_analysis.gif to find the memory leak reason. use the chrome memory tool and analysis report ,We can find The bug because the a3-component.componentInstance.$vnode.parent.componentOptions.children[0] is a4-component.so the a4-component can not be Memory free. If you can read chinese ,Open the link for https://juejin.cn/post/7153186266300252168
Steps to reproduce
We can find The bug because
the a3-component.componentInstance.$vnode.parent.componentOptions.children[0] is a4-component.so the a4-component can not be Memory free.
问题遇到+1
问题遇到+1
看来遇到的人不多,只能换方案去解决了 keepalive的问题 >_<
惊现 面试官
你好,问题解决了么~
你好,问题解决了么~
内存问题没解决,用别的思路规避大量重复创建组件带来的大量内存占用问题。比如共用同一个页签组件不销毁,只是切换data数据。
I have the same issue. Any updates on this?
Any updates on this?
我推测的主要原因是在 /src/core/components/keep-alive.ts
里面清除缓存的方法里面有个判断 if (entry && (!current || entry.tag !== current.tag)) {
导致如果要清除的Entry的tag与当前实例tag相同则跳过了强制destroy,个人认为这里应该使用vnode的key进行进一步判断。如 if (entry && (!current || entry.tag !== current.tag || entry.componentInstance.$vnode.key !== current.key)) {
function pruneCacheEntry(
cache: CacheEntryMap,
key: string,
keys: Array<string>,
current?: VNode
) {
const entry = cache[key]
if (entry && (!current || entry.tag !== current.tag)) {
// @ts-expect-error can be undefined
entry.componentInstance.$destroy()
}
cache[key] = null
remove(keys, key)
}```
I just found that, if you use transition
with keep-alive
, the issue is more severe.
However, if you only use keep-alive, this commit(which was already released in 2.7.16) is indeed enough to solve the issue.
您好,我已收到您的来信,我会尽快回复您!