你有没有遇到过这样的情况?微信里用着好好的小程序,突然变得特别卡,滑不动、点不动,甚至直接闪退。关掉重开又好了,但没多久问题又来。其实,这很可能不是手机性能不行,而是小程序在悄悄“吃内存”,也就是常说的内存泄漏。
什么是小程序内存泄漏?
简单说,就是小程序用了内存之后,本该释放的没释放,一直占着不放。就像你借了朋友一块地种菜,收完菜本该还回去,结果你一直占着,朋友没法再给别人用。时间一长,系统能用的内存越来越少,自然就卡了。
常见泄漏场景有哪些?
最常见的就是事件监听没清理。比如你在页面里绑定了滚动事件或全局监听,跳转到别的页面时没有手动解绑,这个监听依然存在,对应的处理函数和数据也一直被引用,无法被回收。
Page({
onLoad() {
wx.onAccelerometerChange(this.onAcc);
},
onAcc(res) {
console.log(res.x);
},
onUnload() {
// 忘记解绑,就会泄漏
// 正确做法:
wx.offAccelerometerChange(this.onAcc);
}
});
另一个典型是定时器。setInterval 或 setTimeout 在页面销毁后还在运行,里面的回调函数会持续占用内存,尤其是回调里还引用了页面数据的时候。
onLoad() {
this.timer = setInterval(() => {
this.setData({ time: Date.now() });
}, 1000);
},
onUnload() {
// 别忘了清理
clearInterval(this.timer);
}
闭包也可能惹祸
有些人喜欢在方法里返回一个函数,形成闭包来保存状态。但如果这个闭包被外部长期持有,内部变量就一直不会被释放。比如把某个页面方法挂到了全局对象上,即使页面关闭了,这个引用还在。
怎么发现内存泄漏?
微信开发者工具里有“性能”面板,可以实时查看内存使用情况。反复打开关闭同一个页面,如果内存曲线只升不降,那基本可以确定有泄漏。真机调试时也可以通过系统自带的内存监控辅助判断。
避免泄漏的实用建议
凡是注册过的事件监听,务必在 onUnload 里对应取消。定时器统一用变量保存,在页面卸载时集中清理。少用全局变量存储页面级数据,避免意外延长生命周期。复杂的组件记得在合适时机调用 destroy 方法。
小程序体积小,运行环境资源有限,对内存管理比网页更敏感。别觉得代码跑通就行,多留意这些细节,才能让用户体验真正流畅。