Browse Source

fix(reactivity): properly clean up deps, fix memory leak

close #11901
Evan You 1 year ago
parent
commit
8ea5d6d698
1 changed files with 22 additions and 2 deletions
  1. 22 2
      packages/reactivity/src/effect.ts

+ 22 - 2
packages/reactivity/src/effect.ts

@@ -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