From 5737f24a571d640c9d262a2e3d4836eb3b3b7968 Mon Sep 17 00:00:00 2001 From: huliang <498755303@qq.com> Date: Wed, 22 Jul 2026 22:11:12 +0800 Subject: [PATCH] fix: clear descriptorTargetMap on unmount to prevent memory leak descriptorTargetMap accumulates an entry per property whose descriptor is queried through the proxy window (getOwnPropertyDescriptor), but was never cleared. Under repeated mount/unmount (keep-alive, prerender) the map grows without bound and may hold stale routing targets. Lift the map to patchWindow scope, pass it to createProxyWindow and patchWindowEffect, and clear it in release() on every unmount mode. --- src/sandbox/with/window.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sandbox/with/window.ts b/src/sandbox/with/window.ts index 7ba384db..a8538dcd 100644 --- a/src/sandbox/with/window.ts +++ b/src/sandbox/with/window.ts @@ -40,9 +40,10 @@ export function patchWindow ( microAppWindow: microAppWindowType, sandbox: WithSandBoxInterface, ): CommonEffectHook { + const descriptorTargetMap = new Map() patchWindowProperty(microAppWindow) - createProxyWindow(appName, microAppWindow, sandbox) - return patchWindowEffect(microAppWindow, appName) + createProxyWindow(appName, microAppWindow, sandbox, descriptorTargetMap) + return patchWindowEffect(microAppWindow, appName, descriptorTargetMap) } /** @@ -84,9 +85,9 @@ function createProxyWindow ( appName: string, microAppWindow: microAppWindowType, sandbox: WithSandBoxInterface, + descriptorTargetMap: Map, ): void { const rawWindow = globalEnv.rawWindow - const descriptorTargetMap = new Map() rawDefineProperty(microAppWindow, 'Worker', { value: WorkerProxy, @@ -219,7 +220,11 @@ function createProxyWindow ( * Rewrite side-effect events * @param microAppWindow micro window */ -function patchWindowEffect (microAppWindow: microAppWindowType, appName: string): CommonEffectHook { +function patchWindowEffect ( + microAppWindow: microAppWindowType, + appName: string, + descriptorTargetMap: Map, +): CommonEffectHook { const eventListenerMap = new Map>() const sstEventListenerMap = new Map>() const intervalIdMap = new Map() @@ -387,6 +392,9 @@ function patchWindowEffect (microAppWindow: microAppWindowType, appName: string) intervalIdMap.clear() timeoutIdMap.clear() } + + // clear descriptor target cache to avoid unbounded growth on repeated mount/unmount + descriptorTargetMap.clear() } return {