Skip to content

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

@williamChen26

Description

@williamChen26

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions