全局变量阻碍垃圾回收,因其始终可达、长期驻留堆内存、扩大根集扫描开销;隐式全局变量更危险;应通过模块化、弱引用和显式清理缓解。

全局变量过多会直接阻碍垃圾回收(GC)正常工作,因为它们始终处于“可达”状态,无法被标记为可回收对象。
全局变量永不退出活跃作用域
JavaScript 的垃圾回收器主要依赖“可达性分析”判断对象是否可回收。全局变量挂在 window(浏览器)或 globalThis 上,从脚本加载起就一直可被访问,生命周期贯穿整个页面运行期。哪怕你只用了一次,只要没手动切断引用,GC 就永远不能释放它占用的内存。
- 局部变量在函数执行完后自动脱离作用域,栈/堆空间很快被识别并清理
- 全局变量长期驻留堆内存,持续占用空间,还可能意外持有 DOM 节点、大数组、闭包等重型对象
- 变量越多,GC 每次扫描的根对象(root set)越大,标记阶段耗时增加,尤其在低端设备上易引发卡顿
隐式全局变量更危险
没加 let/const/var 直接赋值,比如 data = [],会悄悄挂到全局对象上——这种变量既难发现又无法被 GC 回收。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 严格模式下会报错,强制暴露问题;非严格模式则静默创建,埋下泄漏隐患
- 这类变量常出现在事件回调、定时器、异步操作中,容易累积成千上万个小对象,拖慢 GC 频率与效率
全局引用链延长其他对象寿命
一个全局变量哪怕本身很小,也可能成为“强引用枢纽”,让本该释放的对象继续存活。
立即学习“Java免费学习笔记(深入)”;
- 例如:
window.cacheMap = new Map()存了 100 个 DOM 元素,即使这些元素已从页面移除,只要 map 还在,元素就无法被回收 - 定时器、未解绑的事件监听器、Promise 回调若被全局变量捕获,也会形成持久引用链,阻断 GC 路径
- V8 等引擎的分代回收机制对“老生代”对象更保守,全局变量及其关联对象更容易进入老生代,触发代价更高的全堆回收
模块化与弱引用是有效缓解手段
不靠删除全局变量,而靠从设计源头控制其存在必要性。
- 用 ES 模块(
import/export)封装逻辑,让变量天然受限于模块作用域 - 需跨模块共享数据时,优先用单例类或依赖注入,而非
window.AppData这类裸挂载 - 必须附加元信息时,用
WeakMap替代属性挂载(如element.__config),键为弱引用,目标销毁后条目自动消失 - 组件卸载或路由切换时,主动执行
myGlobalCache = null或cacheMap.clear(),显式解除引用

















