Subscribe on changes!

实现虚拟列表时,发现v-for存在内存泄漏

avatar
Jun 1st 2022

Vue version

^3.2.25

Link to minimal reproduction

https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHRlbXBsYXRlPlxuICA8SGVsbG9Xb3JsZCAvPlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbmltcG9ydCBIZWxsb1dvcmxkIGZyb20gJy4vSGVsbG9Xb3JsZC52dWUnXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ0FwcCcsXG4gIGNvbXBvbmVudHM6IHtcbiAgICBIZWxsb1dvcmxkXG4gIH1cbn1cbjwvc2NyaXB0PlxuXG48c3R5bGU+XG4jYXBwIHtcbiAgZm9udC1mYW1pbHk6IEF2ZW5pciwgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgLXdlYmtpdC1mb250LXNtb290aGluZzogYW50aWFsaWFzZWQ7XG4gIC1tb3otb3N4LWZvbnQtc21vb3RoaW5nOiBncmF5c2NhbGU7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgY29sb3I6ICMyYzNlNTA7XG4gIG1hcmdpbi10b3A6IDYwcHg7XG59XG48L3N0eWxlPlxuIiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCIsXG4gICAgXCJ2dWUvc2VydmVyLXJlbmRlcmVyXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3NlcnZlci1yZW5kZXJlci5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0iLCJIZWxsb1dvcmxkLnZ1ZSI6Ijx0ZW1wbGF0ZT5cbiAgPGRpdiBjbGFzcz1cImhlbGxvXCI+XG4gICAgPGRpdiB2LWZvcj1cIml0ZW0gaW4gZGlzcGxheUl0ZW1zXCIgOmtleT1cIml0ZW0ua2V5XCI+XG4gICAgICAgIDxUZXN0PlxuICAgICAgICAgIDxkaXY+I3t7IGl0ZW0ua2V5IH19PC9kaXY+XG4gICAgICAgIDwvVGVzdD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuaW1wb3J0IHsgcmVmIH0gZnJvbSAndnVlJztcbmltcG9ydCBUZXN0IGZyb20gJy4vdGVzdC52dWUnO1xuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAnSGVsbG9Xb3JsZCcsXG4gIGNvbXBvbmVudHM6IHtcbiAgICBUZXN0LFxuICB9LFxuICBwcm9wczoge1xuICAgIG1zZzogU3RyaW5nXG4gIH0sXG4gIHNldHVwKCkge1xuICAgIGNvbnN0IGRhdGEgPSByZWYoW10pO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCAxMDAwMDsgaW5kZXgrKykge1xuICAgICAgZGF0YS52YWx1ZS5wdXNoKHtcbiAgICAgICAga2V5OiBpbmRleCxcbiAgICAgIH0pXG4gICAgICBcbiAgICB9XG4gICAgY29uc3QgZGlzcGxheUl0ZW1zID0gcmVmKFtdKTtcbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5Jyk7XG4gICAgbGV0IG51bSA9IDE7XG4gICAgY29udGFpbmVyLm9uc2Nyb2xsID0gKCkgPT4ge1xuICAgICAgY29uc3Qgc2Nyb2xsVG9wID0gY29udGFpbmVyLnNjcm9sbFRvcCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgICBpZiAoc2Nyb2xsVG9wID4gMTAwMCAqIG51bSkge1xuICAgICAgICBjb25zb2xlLmxvZygxMTExKVxuICAgICAgICBudW0rKztcbiAgICAgICAgZGlzcGxheUl0ZW1zLnZhbHVlID0gZGF0YS52YWx1ZS5zbGljZSgxMDAwICogKG51bSAtIDEpLCAxMDAwICogbnVtKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZGlzcGxheUl0ZW1zLnZhbHVlID0gZGF0YS52YWx1ZS5zbGljZSgwLCAxMDAwKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YSxcbiAgICAgIGRpc3BsYXlJdGVtcyxcbiAgICB9XG4gIH1cbn1cbjwvc2NyaXB0PlxuXG48IS0tIEFkZCBcInNjb3BlZFwiIGF0dHJpYnV0ZSB0byBsaW1pdCBDU1MgdG8gdGhpcyBjb21wb25lbnQgb25seSAtLT5cbjxzdHlsZSBzY29wZWQ+XG5oMyB7XG4gIG1hcmdpbjogNDBweCAwIDA7XG59XG51bCB7XG4gIGxpc3Qtc3R5bGUtdHlwZTogbm9uZTtcbiAgcGFkZGluZzogMDtcbn1cbmxpIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBtYXJnaW46IDAgMTBweDtcbn1cbmEge1xuICBjb2xvcjogIzQyYjk4Mztcbn1cbjwvc3R5bGU+XG4iLCJ0ZXN0LnZ1ZSI6Ijx0ZW1wbGF0ZT5cbiAgPGRpdj5cbiAgICAgIDxzbG90IC8+XG4gIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAndGVzdCcsXG5cbn1cbjwvc2NyaXB0PlxuIn0=

Steps to reproduce

  1. 页面持续往下滚动,displayItems数组会根据滚动高度刷新数据,v-for循环展示displayItems,当displayItems数组改变时,dom重新渲染,旧dom被销毁 2.通过chrome的开发工具可以看到,旧dom已经被销毁了,但是并没有被回收,还存在内存中。dom节点不断增大,内存占用也在增加。

What is expected?

预期效果应该是旧dom会被回收。

What is actually happening?

奇怪的是,当循环中存在vue组件时,才会出现该问题,如 image test组件 image

当我把vue组件去掉时,垃圾回收机制就正常了,销毁的dom能正常被回收 image

下面是我在虚拟列表的上下滚动时所录制的内存情况 image (vue2不会出现这种情况)

System Info

No response

Any additional comments?

No response

avatar
Jun 15th 2022

play 这样会回收吗

这个看起来并是不我想要的虚拟列表

avatar
Jun 15th 2022

你是不是开 dev tools 了

avatar
Oct 31st 2022

也遇到了这个问题,v-for下动态组件列表,内存泄漏,尤其通过组件属性,往组件里传递大数组时,泄漏非常快,比如上面

<Test data="ArraySize_5K"> ... </Test>
avatar
Jan 16th 2023

你是不是开 dev tools 了

关了有用,回收变快了

avatar
Jan 16th 2023

你是不是开 dev tools 了

牛蛙 确实关了就可以正常回收了

avatar
Jan 17th 2023