内存泄漏

1.什么是内存泄漏?

内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
 

2.内存泄漏有什么危害?

 1、频繁GC:系统分配给每个应用的内存资源都是有限的,内存泄漏导致其他组件可用的内存变少后,一方面会使得GC的频率加剧,再发生GC的时候,所有进程都必须等待,GC的频率越高,用户越容易感应到卡顿。另一方面内存变少,可能使得系统额外分配给该对象一些内存,而影响整个系统的运行情况。
 
 2、导致程序运行崩溃:一旦内存不足以为某些对象分配所需要的空间,将会导致程序崩溃,造成体验差。
 

3.什么原因能够产生内存泄漏?

 1.对文件进行操作后,忘记close
 2.滥用全局变量, 一直往全局变量添加值,未进行delete
 3.代码中有“引用循环”,就会发生内存泄露
 

4.如何防御内存泄露?

 a.获取一个文件描述符后,操作完成后close
 b.只用全局变量后需要添加del操作
 c.循环引用时使用弱引用不会增加计数器的值
 d.发开接口完成后,使用排查工具检查一下。
 

5.如何发现内存泄漏?

 a.强大的监控报警系统,当内存达到某值时,通过短信邮箱电话等方式告知。
 b.线上服务功能延迟卡顿,或服务不可用。
 
 

6.发生了内存泄漏如何排查?

 a. python垃圾回收机制
引用计数: 每个对象中都有ob-refcnt来做引用计数。当一个对象...,ob-refcnt就会增加,当引用的对象删除,                  那么ob-refcnt就会减少当ob-refcnt为零,就会释放该对象的内存空间
标记清除: 解决循环引用的问题。先按需分配,等到没有空闲内存的时候,从寄存器和程序栈上的引用出发,遍历所有对象和引用把所有能访问的打标记,最后将没有标记的对象释放掉
分代技术: 提高效率,提高垃圾回收的效率,按照存活时间,分成不同的集合。将内存块按照其存活时间划分为不同的集合。每个集合就称为一个“代”,垃圾回收的频率随代的存活时间增大而减小。Python默认定义分代对象集合,引用数越大,对象的存活时间越长
 
b.python内存排查工具
1.objgraph
  objgraph.show_growth(limit=20)

2.pympler
  from pympler import tracker
    tr = tracker.SummaryTracker()
    tr.print_diff()
 
c.排查技巧
a.对每一个接口压测,观察对象引用无变化则进行下一次接口,
b.发现内存泄漏接口时,同时观察内存变化和日志变化的关系
c.接口层(大范围)->服务层(小范围)->代码块(更小范围)
 

7.一次有趣的内存泄漏排查过程?

服务状态:
1652859370646.jpg
 

定位问题:

1.分析内存泄漏的变化趋势,发现在白天时较为明显。→接口调用驱动泄漏
image.png
 
 
2.对推送中心对外开发的接口依次压测,观察内存变化情况
 
在websocket建立连接处和断开连接处分别打对象引用情况
 
WeChat2cd5c14a63079ae069a463f7bb19fa87.png
WeChat632b47d3f896649789fcd7f600e89cba.png
 
观察日志发现token失效时,内存发生泄漏。→AES库存在内存泄漏?
 
3.分析代码
 
 
raise ConnectionRefusedError() 有错误
 

分析原因:

1.连接未断开,尝试return 和 sio.disconnect()
 
2.查找官方文档
image (3).png
3.跟踪源代码
image.png
 
 

解决问题:

from socketio.exceptions import ConnectionRefusedError
 
posted @ 2022-05-29 10:27  阿莫夕林  阅读(588)  评论(0)    收藏  举报