You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Store内存持续增长:旧状态未释放引发异常

Angular NgRx Store 内存未释放问题排查

我在测试Angular应用时发现异常行为:每次用新数组覆盖Store中的数据,旧状态似乎仍驻留在内存中(仅最新的条形图应为蓝色)。
内存异常的条形图

测试触发代码

为测试,我每5秒分发10次加载动作:

ngOnInit() {
  setInterval(() => {
    for (let i = 0; i < 10; i++) {
      this.store.dispatch(CharacterActions.getCharacters());
    }
  }, 5000);
}

Store 定义

export interface CharacterState {
  characters: Character[];
}

export const initialState: CharacterState = {
  characters: [],
};

export const characterReducer = createReducer(
  initialState,
  on(CharacterActions.getCharactersSuccess, (state, { characters }) => ({
    ...state,
    characters: [...characters],
  }))
);

Character 类定义

import { Weapon } from "./weapon";

export class Character {
    name: string;
    surname: string;
    private weapons: Weapon[];

    constructor(name: string, surname: string, weapons?: Weapon[]) {
        this.weapons = weapons ?? [];
        this.name = name;
        this.surname = surname;
    }

    public getWeapons(): Weapon[] {
        return this.weapons;
    }

    public addWeapon(weapon: Weapon): void {
        this.weapons.push(weapon);
    }

    public upgradeWeapon(name: string, value: number) {
        this.weapons.find(x => x.name === name.toLowerCase())?.upgrade(value);
    }
}

内存未释放的可能原因

  • 引用未彻底切断:虽然reducer里用[...characters]创建了新数组,但如果Character实例或其内部weapons数组被外部组件/服务持有引用,垃圾回收器无法回收旧数据。比如组件订阅Store后未取消订阅,或某处缓存了旧Character对象。
  • NgRx DevTools 保留历史:若开启NgRx DevTools,它默认保留所有状态历史用于调试,会导致旧状态被持有无法回收。可检查StoreModule.forRoot中的maxAge配置,限制历史状态数量。
  • Character类的引用泄漏:getWeapons()直接返回内部数组引用,外部代码若持有该引用,会导致对应Character实例无法被回收。应返回数组副本:return [...this.weapons];。
  • 未清理的定时器:setInterval创建的定时器若未在组件销毁时清除,会持续触发动作,且回调持有组件实例引用,导致组件及相关Store数据无法回收。需在ngOnDestroy中调用clearInterval清理。
  • 异步订阅泄漏:getCharacters()对应的Effect若有未取消的HTTP订阅,或订阅Store时未用takeUntil、async管道自动取消,会导致旧订阅持有状态引用。

内容的提问来源于stack exchange,提问作者Groomer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:25:23