这篇文章因为涉及的点比较多,所以我没有一次完成,在持续补充中,有些章节缺失,我在尽快补充中
一、C#cpu飙高和内存飙高。
1)Debug环境下的飙高
Visual Studio的新版本自带了诊断工具,如果你写的c#程序在调试阶段就表现出了内存飙高或者cpu飙高,那么你用vs的诊断工具,就可以找出是哪块代码引起的。比如cpu飙高的问题,想重现cpu飙高,只要写一个死循环就可以。
static void Main(string[] args)
{
try
{
Thread thread = new Thread(() =>
{
Test();
});
thread.Start();
}
catch (Exception ex)
{
}
Console.ReadLine();
}
private static void Test()
{
while (true)
{
Console.WriteLine(DateTime.Now.Ticks);
}
}
这段代码一旦启动,就会导致我的cpu飙高到30%。诊断工具,只要在vs启动项目的时候一般就会跟着打开,如果没有打开,那么按照这个路径:调试=》窗口=》显示诊断工具,然后会看到下面的界面:
点击记录CPU配置文件,让它前面的圆圈变成红色。这个功能必须在你设置了断点,或者vs给你把程序中断的情况下才能看到具体的统计信息,因为统计信息是不停地变地,如果程序继续运行,那么就无法确定统计范围了。
点击全部中断:
等信息收集好之后就可以看到上面的cpu使用率统计了。有些情况下可能会提示没有数据,那就重启一下你的项目,让程序运行久点,应该就有了。
单击下面的Test方法的链接,在新界面里面双击Test,可以看到这个界面:
可以很清晰地看到是哪段代码占用了cpu。
对于内存飙高的情况,则是使用那个内存使用率。写下面的代码:
class Program
{
static void Main(string[] args)
{
try
{
new Thread(() => { Test(); }).Start();
}
catch (Exception){ }
Console.ReadLine();
}
static Dictionary<long, Student> dic = new Dictionary<long, Student>();
private static void Test()
{
while (true)
{
long l = DateTime.Now.Ticks;
dic.Add(l, new Student() { ID = l });
Console.WriteLine(l);
Thread.Sleep(500);
}
}
}
class Student
{
public long ID { set; get; }
}
运行一段时间后,点击内存使用率,点击截取快照:
点击对象那一列的数字链接:
可以很清楚地看到Student这个类地 计数是505次,大小是12120字节。
2)线上环境的飙高
大部分场景下,都是线上环境的飙高。这里又分两种情况
1)分析远程服务器(比如Linux、Docker)上运行的程序。
2)分析未装有vs的某一台生产电脑上运行的.net程序。
以上两种情况还是使用vs自带的诊断工具来排查,只是由原来的诊断工具连接本地运行的程序改到了链接服务器或者远程计算机运行的程序,如何进行远程链接呢,方法是使用附加进程的方式。具体步骤如下:
a)如果要链接远程计算机,那么需要在目标计算机上运行远程调试工具。下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/?rr=https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019。进到页面后,找到Visual Studio 2019工具:
b)下载之后在目标机上安装,运行,界面如下:
尽量以管理员方式运行。
c)点击工具=》选项:
这里为了简单,使用无身份验证,即允许任何人都可以调试这台电脑,你也可以选择身份验证的方式,根据你自己的需要来定。
设置好之后的页面如下:
d)在本地用vs打开你要调试的项目的源代码,选择调试=》附加到进程。选择无身份验证,点击查找就可以找到刚才我们要进行远程的目标机器了,只要两台机器在同一个网络里面,远程工具会自动搜索可以远程调试的机器:
选择这台准备好的机器,就可以看到可以附加的进程了,如下图,是我写的一个测试程序,选中它,点击附加:
等待加载好符号,然后你的机器就像调试本地代码一样可以随意调试它了。进入到vs调试之后,原来的诊断工具就可以使用了,它的使用方式,在上一步中已经说了。
注意:这里要注意的是,如果你想单步debug,那么你运行的程序包应该是debug里面,包含了调试信息的。如果你运行的包是release的,会缺少一些调试信息,在进行debug的时候,可能会受限,比如断点无法命中。如果你在打包的时候选择不包含调试信息,比如我在我的另一篇博客里面提到的那种打包方式,那么你基本无法进行单步debug。但是不管哪种包,vs的诊断工具都是可以使用的,是不影响你排查cpu和内存飙高问题的。
二、程序遇到异常发生崩溃
如果程序遇到异常发生崩溃,那么通常的手段,打印日志,远程调试,都没法使用了,这个时候你可以试试调试dmp文件,具体方法参考我另外一篇博客:https://blog.csdn.net/dap769815768/article/details/105506072
三、代码慢
一个业务代码的运行过程大概包含以下几个过程:
1)功能代码执行时间太久
分析代码。在vs里面有性能监控,如果没有源码,在生产环境,可以使用远程资源监控。这部分参考“线上环境的飙高”解决办法。
2)数据库请求执行时间太久
- 使用相关工具查询数据库的sql记录
- 使用explain分析sql语句。在pg里面可以加上analyze进行分析: explain analyze select * from cash union all select * from cash
这部分可以参考我的另外一篇博客:https://blog.csdn.net/dap769815768/article/details/105792481
3)网络请求时间太久
使用ping就可以查看到网络的请求响应时间。