小程序页面之间跳转,多次操作,小程序便会卡死问题
发布于 6 年前 作者 zsong 8104 次浏览 来自 问答

小程序页面A 通过<navigate>跳转到页面B。

页面B通过小程序自带的顶部返回按钮,返回页面A。

重复A到B,B返回A 操作。

小程序就有可能卡死。

A页面内容仅<navigate>标签。B页面仅几个表单字段。B返回A,并未做表单提交。

调试工具还有一个报错异常:

 (node) warning: possible EventEmitter memory leak detected. 16 listeners added. Use emitter.setMaxListeners() to increase limit. 

1 回复

内存泄漏(Memory Leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。 

导致内存泄漏的原因: 

① 全局变量:全局变量直接挂在 root 对象上,不会被清除掉

a = 10;//未声明对象。

global.b = 11;//全局变量引用

② 闭包:闭包会引用到父级函数中的变量,如果闭包未释放,就会导致内存泄漏。上面例子是 inner 直接挂在了 root 上,那么每次执行 out 函数所产生的 bigData 都不会释放,从而导致内存泄漏。

function out() {

  const bigData = new Buffer(100);

  inner = function () {

    void bigData;

  }

}

③ 事件监听:Node.js 的事件监听也可能出现的内存泄漏。例如对同一个事件重复监听,忘记移除(removeListener),将造成内存泄漏。这种情况很容易在复用对象上添加事件时出现,所以事件重复监听可能收到如下警告:

(node:2752) Warning: Possible EventEmitter memory leak detected。11 haha listeners added。Use emitter。setMaxListeners() to increase limit

1

④其他原因:还有一些其他的情况可能会导致内存泄漏,比如缓存、非常占用 CPU 的代码等。 

虽然只是警告,但有时候会影响到其他事件的执行,且,控制台上存在标红时,相信每一个程序员的心里应该都是不太舒服的。 

避免内存泄漏方式: 

① ESLint 检测代码检查非期望的全局变量。 

② 使用闭包的时候,得知道闭包了什么对象,还有引用闭包的对象何时清除闭包。最好可以避免写出复杂的闭包,因为复杂的闭包引起的内存泄漏,如果没有打印内存快照的话,是很难看出来的。 

③ 绑定事件的时候,一定得在恰当的时候清除事件。在编写一个类的时候,推荐使用 init 函数对类的事件监听进行绑定和资源申请,然后 destroy 函数对事件和占用资源进行释放。 

解决方法:

const emitter = new EventEmitter()

emitter.setMaxListeners(100)//指定一个最大监听数量

emitter.setMaxListeners(0)//或者关闭最大监听阈值

回到顶部