]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): properly clean up deps, fix memory leak
authorEvan You <evan@vuejs.org>
Fri, 13 Sep 2024 10:34:59 +0000 (18:34 +0800)
committerEvan You <evan@vuejs.org>
Fri, 13 Sep 2024 10:35:16 +0000 (18:35 +0800)
close #11901

packages/reactivity/src/effect.ts

index 32ea8ee0c814a143a8557aa809b5567e636a910b..0c05e06075571fcfdae7586945b0e507e68e87f0 100644 (file)
@@ -208,6 +208,23 @@ export class ReactiveEffect<T = any>
   }
 }
 
+/**
+ * For debugging
+ */
+// function printDeps(sub: Subscriber) {
+//   let d = sub.deps
+//   let ds = []
+//   while (d) {
+//     ds.push(d)
+//     d = d.nextDep
+//   }
+//   return ds.map(d => ({
+//     id: d.id,
+//     prev: d.prevDep?.id,
+//     next: d.nextDep?.id,
+//   }))
+// }
+
 let batchDepth = 0
 let batchedEffect: ReactiveEffect | undefined
 
@@ -265,9 +282,11 @@ function cleanupDeps(sub: Subscriber) {
   // Cleanup unsued deps
   let head
   let tail = sub.depsTail
-  for (let link = tail; link; link = link.prevDep) {
+  let link = tail
+  while (link) {
+    const prev = link.prevDep
     if (link.version === -1) {
-      if (link === tail) tail = link.prevDep
+      if (link === tail) tail = prev
       // unused - remove it from the dep's subscribing effect list
       removeSub(link)
       // also remove it from this effect's dep list
@@ -281,6 +300,7 @@ function cleanupDeps(sub: Subscriber) {
     // restore previous active link if any
     link.dep.activeLink = link.prevActiveLink
     link.prevActiveLink = undefined
+    link = prev
   }
   // set the new head & tail
   sub.deps = head