Skip to content

Commit

Permalink
fix(reactivity): fix memory leak from dep instances of garbage collec…
Browse files Browse the repository at this point in the history
…ted objects

close #11979
close #11971
  • Loading branch information
yyx990803 committed Sep 20, 2024
1 parent 5c8b76e commit 235ea47
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
13 changes: 12 additions & 1 deletion packages/reactivity/src/dep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ export class Dep {
*/
subsHead?: Link

/**
* For object property deps cleanup
*/
target?: unknown = undefined
map?: KeyToDepMap = undefined
key?: unknown = undefined

constructor(public computed?: ComputedRefImpl | undefined) {
if (__DEV__) {
this.subsHead = undefined
Expand Down Expand Up @@ -218,7 +225,8 @@ function addSub(link: Link) {
// which maintains a Set of subscribers, but we simply store them as
// raw Maps to reduce memory overhead.
type KeyToDepMap = Map<any, Dep>
const targetMap = new WeakMap<object, KeyToDepMap>()

export const targetMap: WeakMap<object, KeyToDepMap> = new WeakMap()

export const ITERATE_KEY: unique symbol = Symbol(
__DEV__ ? 'Object iterate' : '',
Expand Down Expand Up @@ -249,6 +257,9 @@ export function track(target: object, type: TrackOpTypes, key: unknown): void {
let dep = depsMap.get(key)
if (!dep) {
depsMap.set(key, (dep = new Dep()))
dep.target = target
dep.map = depsMap
dep.key = key
}
if (__DEV__) {
dep.track({
Expand Down
20 changes: 13 additions & 7 deletions packages/reactivity/src/effect.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { extend, hasChanged } from '@vue/shared'
import type { ComputedRefImpl } from './computed'
import type { TrackOpTypes, TriggerOpTypes } from './constants'
import { type Link, globalVersion } from './dep'
import { type Link, globalVersion, targetMap } from './dep'
import { activeEffectScope } from './effectScope'
import { warn } from './warning'

Expand Down Expand Up @@ -418,13 +418,19 @@ function removeSub(link: Link) {
dep.subsHead = nextSub
}

if (!dep.subs && dep.computed) {
if (!dep.subs) {
// last subscriber removed
// if computed, unsubscribe it from all its deps so this computed and its
// value can be GCed
dep.computed.flags &= ~EffectFlags.TRACKING
for (let l = dep.computed.deps; l; l = l.nextDep) {
removeSub(l)
if (dep.computed) {
// if computed, unsubscribe it from all its deps so this computed and its
// value can be GCed
dep.computed.flags &= ~EffectFlags.TRACKING
for (let l = dep.computed.deps; l; l = l.nextDep) {
removeSub(l)
}
} else if (dep.map) {
// property dep, remove it from the owner depsMap
dep.map.delete(dep.key)
if (!dep.map.size) targetMap.delete(dep.target!)
}
}
}
Expand Down

0 comments on commit 235ea47

Please # to comment.