Visual Studio 2022分析C#程序内存泄漏

背景

最近我们的项目出现了内存激增的情况,初次探讨,我们发现和机器人发生通信之后,内存会缓慢上升,直到系统崩溃。

例子

由于只是介绍一个简单的方案,所以就写一个比较简单的例子来演示了,代码如下:

internal class Program
{
    static void Main(string[] args)
    {
        Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
        for(int i = 0; i < 100000000; i++)
        {
            dict[i]=new List<int>();
            for(int j = 0; j < 100000000; j++)
            {
                dict[i].Add(j);
            }
            Console.WriteLine($"dict[{i}].Count={dict[i].Count}");
        }
        Console.WriteLine($"dict.Count={dict.Count}");
    }
}

不难看出,这是一个故意写成内存泄漏的例子,其中创建一个字典dict,键为整数,值也为整数,不断创建对象放入字典中,内存会不断增长,最终崩溃。

调试

1.打开vs2022,把项目的启动方式改为Release

2.选择“调试->性能探测器”

3.勾选内存使用率项,然后开始检测

4.检测的过程中,我们可以对当前内存中各对象的占用情况进行多次抓拍

5.抓拍了差不多的时候,就可以停止收集,开始分析

 

 6.如上,我们选择最后一个抓拍的结果,点击查看堆

7.东西有点多,是不是看不懂,没关系,选择显示死对象,因为内存泄漏很多情况都是因为死对象没得到释放造成的。

8.还是太多,不过已经能看出是一个Int32数组的问题,我们还可以继续过滤其他的,选择代码中的大型对象。

9.点击最终锁定的Int32[],会看到其调用情况

10. C#中List底层就是一个数组来维护的,点击List<int>继续展开

可以看到,已经精准定位到字典的问题,因为代码是我们写的,这个字典在哪里进行调用,我们自己很清楚,于是就有了排查的方向。 

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中可以通过垃圾回收器(Garbage Collector)来判断是否存在内存泄漏。垃圾回收器是C#的一种自动内存管理机制,它会在程序运行时自动监视和回收不再使用的内存。 首先,让我们了解一下什么是内存泄漏内存泄漏指的是程序中的一块内存被分配后,无法被释放或重新使用,导致这块内存无法被垃圾回收器回收。如果程序中的内存泄漏问题严重,将会导致内存占用不断增加,最终可能导致程序崩溃或者系统资源耗尽。 在C#中,可以通过以下几种方式判断是否存在内存泄漏: 1. 使用性能分析器:C#提供了一些性能分析工具,如Visual Studio性能分析器,可以帮助你检测内存泄漏问题。你可以使用这些工具来监视内存使用情况,并查看是否有未释放的对象。 2. 注意使用Dispose()方法:如果你使用了实现了IDisposable接口的对象(如FileStream、SqlConnection等),则应该在使用完毕后显式调用Dispose()方法来释放资源。确保你正确地使用了using语句或手动调用Dispose()方法来释放资源。 3. 避免循环引用:在C#中,如果存在循环引用的情况,垃圾回收器将无法回收相关的对象。确保你在对象之间建立正确的引用关系,避免出现循环引用的情况。 4. 注意事件订阅和取消订阅:如果你在程序中使用了事件,务必在不再需要订阅事件时主动取消订阅。如果不取消订阅,事件发布者仍然会持有对订阅者的引用,导致内存无法释放。 总的来说,合理使用垃圾回收器、正确释放资源、避免循环引用和及时取消事件订阅等是判断和解决C#内存泄漏问题的关键。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值