当前位置: 首页 > news >正文

C# --- 单例类错误初始化 + 没有释放资源导致线程泄漏

C# --- 单例类错误初始化 + 没有释放资源导致线程泄漏

  • Background
  • 原因分析
    • 问题一: 错误初始化(使用了箭头函数)
    • 问题一: 没有Dispose资源

Background

  • 背景: service A的其中一个Api会向mq发送消息
  • 问题:线上发现这个服务经常有几百个线程在同时运行,怀疑是发生了线程泄漏
  • 什么是线程泄漏:代码产生了大量的不应该出现的线程,导致占用过多资源,严重影响系统性能

原因分析

经过排查发现了一下问题代码

public class Dispatch
{public static Dispatch Instance => new Dispatch();private readonly Sender senderpublic Dispatch() { sender = new Sender();}
}public class Sender : IDisposable
{private readonly Task _recoveryTask;public Sender() { recoveryTask = Task.Factory.StartNew(new Action(this.ReceoveryTaskEntry), TaskCreationOptions.LongRunning)}private void RecoveryTaskEntry() {while (!this.Disposed){//impl}}public void Dispose() {_recoveryTask.Dispose()GC.SuppressFinalize(this); // 阻止终结器调用}
}

问题一: 错误初始化(使用了箭头函数)

public static Dispatch Instance => new Dispatch();//等价于
public static Dispatch Instance() 
{return new Dispatch();
}

以上代码在 Dispatch.Insatnce被调用时每次都会新建一个Dispatch实例,而Dispatch的构造方法里会创建并运行一个新的线程,也就是说每个requets都会创建一个新的线程

正确的初始化:保证单例类只有一个实例

public static Dispatch Instance { get; } = new Dispatch();

问题一: 没有Dispose资源

在Dispatch中没有dispose sender, 导致线程没有被释放

public class Dispatch
{public static Dispatch Instance => new Dispatch();private readonly Sender senderpublic Dispatch() { sender = new Sender();}
}

正确实现:在Dispose中释放资源

public class Dispatch
{public static Dispatch Instance => new Dispatch();private readonly Sender senderpublic Dispatch() { sender = new Sender();}public void Dispose() {sender.Dispose()//....}
}
http://www.xdnf.cn/news/1133191.html

相关文章:

  • 实训十一——网络通信原理
  • WP Force SSL Pro – HTTPS SSL Redirect Boost Your Website‘s Trust in Minutes!
  • ByteToMessageDecoder详解
  • 神经网络常见激活函数 13-Softplus函数
  • Linux4:线程
  • 7.16 Java基础 | 集合框架(上)
  • SM3算法工程中添加bouncycastle.bcprov.jdk15on库
  • 从函数调用到进程通信:Linux下的多语言协作实践
  • MySQL 8.0 OCP 1Z0-908 题目解析(27)
  • 解决“Windows 无法启动服务”问题指南
  • 论文导读--PQ3D:通过分段级分组实现多模态特征融合和 MTU3D:在线查询表示学习与动态空间记忆
  • C# 8.0 创建一个简单的控制台应用程序
  • 使用 CrewAI 进行股票分析:自动化投资决策的新途径
  • YAML 自动化用例中 GET vs POST 请求的参数写法差异
  • 剑指offer64_圆圈中最后剩下的数字
  • 分块(chunked) vs 滑动窗口(windowed)
  • 力扣面试150(31/150)
  • Python爬虫实战:研究PyYAML库相关技术
  • 工作第一步建立连接——ssh
  • STM32硬件I2C的注意事项
  • UniApp 多端人脸认证图片上传实现
  • Sketch 与 Figma
  • 基于 Python/PHP/Node.js 的淘宝 API 商品数据抓取开发教程
  • 个人笔记(linux/sort与uniq命令)
  • [硬件电路-28]:从简单到复杂:宇宙、芯片与虚拟世界的共通逻辑
  • 快速掌握 Kafka:从核心概念到生产级部署指南
  • 网络安全初级(XSS-labs 1-8)
  • 基于Canal实现MySQL数据库数据同步
  • 数字IC后端培训教程之数字后端项目典型项目案例解析
  • 端侧推理软件栈