内存泄漏怎么处理

什么是内存泄漏?

程序的运行需要内存。只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存。

对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能:变慢,延迟大等 ,重则导致进程崩溃。

不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。

内存泄漏的识别方法

1. 使用快捷键 F12 或者 Ctrl+Shift+J 打开 Chrome 浏览器的「开发者工具」
2. 选择 Performance(老版为Timeline) 选项卡,在 Capture 选项中,只勾选 Memory
3. 设置完成后,点击最左边的 Record 按钮,然后就可以访问网页了。
4. 打开一个网站,例如:www.taobao.com当网页加载完成后,点击 Stop,等待分析结果。
5. 然后在 Chart View 上寻找内存急速下降的部分,查看对应的 Event Log,可以从中找到GC 的日志。

具体过程如下图所示:

内存泄露的常见原因及处理方式

常见原因:

1. 意外的全局变量

下面代码中变量barfoo函数内,但是bar并没有声明JS就会默认将它变为全局变量,这样在页面关闭之前都不会被释放

function foo(){
  bar=2
  console.log('bar没有被声明!')
}
  • b 没被声明,会变成一个全局变量,在页面关闭之前不会被释放.使用严格模式可以避免.
2. dom清空时,还存在引用

很多时候,为了方便存取,经常会将 DOM 结点暂时存储到数据结构中.但是在不需要该DOM节点时,忘记解除对它的引用,则会造成内存泄露.

var element = {
  shotCat: document.getElementById('shotCat')
};

document.body.removeChild(document.getElementById(‘shotCat’));
// 如果element没有被回收,这里移除了 shotCat 节点也是没用的,shotCat 节点依然留存在内存中.

  • 与此类似情景还有: DOM 节点绑定了事件, 但是在移除的时候没有解除事件绑定,那么仅仅移除 DOM 节点也是没用的
3. 定时器中的内存泄漏
var someResource = getData();
setInterval(function() {
  var node = document.getElementById('Node');
  if(node) {
    node.innerHTML = JSON.stringify(someResource));
  }
}, 1000);
  • 如果没有清除定时器,那么 someResource 就不会被释放,如果刚好它又占用了较大内存,就会引发性能问题. 但是 setTimeout ,它计时结束后它的回调里面引用的对象占用的内存是可以被回收的. 当然有些场景 setTimeout 的计时可能很长, 这样的情况下也是需要纳入考虑的.
4. 不规范地使用闭包

相互循环引用.这是经常容易犯的错误,并且有时也不容易发现.

例如:

function foo() { 
  var a = {}; 
  function bar() { 
    console.log(a); 
  }; 
  a.fn = bar; 
  return bar; 
};
  • bar和a形成了相互循环引用.可能有人说bar里不使用console.log(a)不就没有引用了吗就不会造成内存泄露了.NONONO,bar作为一个闭包,即使它内部什么都没有,foo中的所有变量都还是隐式地被 bar所引用。 即使bar内什么都没有还是造成了循环引用,那真正的解决办法就是,不要将a.fn = bar.

避免策略:

1. 减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收(即赋值为null);
2. 注意程序逻辑,避免“死循环”之类的 ;
3. 避免创建过多的对象 原则:不用了的东西要记得及时归还。
4. 减少层级过多的引用

Node中的内存泄漏

node中的内存泄露与JS中的处理方法稍有不同,详细可以查看这篇文章,非常的详细!

在Linux中处理内存泄漏的方法有多种。首先,可以使用内存泄漏检测工具来帮助定位和解决问题。一些常用的内存泄漏检测工具包括mtrace、memwatch、valgrind和debug_new。这些工具可以帮助开发人员找到内存泄漏的位置和原因,从而进行修复。\[1\] 另外,对于隐式内存泄漏,需要特别注意。隐式内存泄漏指的是程序在运行过程中不停地分配内存,但直到结束时才释放内存。虽然最终程序释放了所有申请的内存,但对于长时间运行的服务器程序来说,不及时释放内存可能导致系统内存耗尽。因此,需要及时释放内存以避免隐式内存泄漏。\[2\] 此外,还需要注意一次性内存泄漏和偶发性内存泄漏。一次性内存泄漏指的是只会发生一次且仅有一块内存发生泄漏的情况,例如在一个Singleton类的构造函数中分配内存,在析构函数中没有释放该内存。而偶发性内存泄漏是由于算法上的缺陷导致的,可能会导致内存泄漏。对于这些情况,需要仔细检查代码并确保正确释放内存。\[3\] 综上所述,处理Linux内存泄漏的方法包括使用内存泄漏检测工具、及时释放内存以避免隐式内存泄漏,并注意一次性内存泄漏和偶发性内存泄漏的情况。 #### 引用[.reference_title] - *1* *2* *3* [Linux内存泄漏检查工具](https://blog.csdn.net/weixin_42275611/article/details/105826846)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值