c# 排查cpu高的函数和内存高的对象

一,背景

最近自己对c# 写的程序进行优化,我首先看代码,分析哪些代码是有问题,这种方式最枯燥,效率也不高,很难发现代码有问题。于是我发现c# 调试会有一个诊断工具,我们可以对内存快照和cpu使用率进行记录

二,逻辑

这种分析通过内存对象引用对象和占内存大小,进行分析,内存分析比较麻烦,必须自己对程序有比较多理解,结合逻辑分析。

CPU分析比较简单,通过时间段分析,哪些占用CPU比较高,然后对应分析就能很快分析出来。

三,例子

待补充,等以后专门记录分析。暂时记录一下,一个知识点记录。

自己也有别的内存泄漏分析工具,但实际效果不是那么好,虽然有一些帮助,这类解决分析,还是看应用和调用过程,如果引用的数目过高,如果不符合自己预期,基本就是有泄漏了。我觉得c#内存泄漏反而不是那么好排查,如果c++ 可能好一点,因为c#有GC,什么时候被释放这个是底层来实现的。c++ 我直接delete,我只要记录哪些是New的对象,然后过一段时间后,然后去检测没有被释放对象有哪些,再根据代码就比较容易找出来。

c# 在子线程然回调到主线程方法

背景

我们开发代码经常面对线程的问题,多线程性带来异步方便的同时也带来稳定性问题,所以我们需要解决掉线程问题

解决方案

1:加锁

这种方案基本是解决线程的基本方法,但要求开发者对代码非常清晰,不然很容易死锁。

2:投递回调或者事件到主线程或者同一个线程里面

基本原理尽可能在同一个线程里面,那么就没有线程竞争,这种实现方式基于主线程的队列,我们常常用主线程的消息队列,c# 貌似也是类似。只要事件队列加锁就可以了,那么加锁颗粒就非常少了,我们也可以自己创建一个线程,不停等待任务,然后处理返回数据,那么数据都在所谓的业务主线程。你可以看看很多开源代码基本这么写的,android 事件也类似。android每个线程都有一个时间循环队列,比喻我们请求网络数据后,直接投递数据到android ui的主线程就可以了,那么数据就没有竞争。

3:c#的方式

SynchronizationContext 这个每个线程都有

            sync_context.Post(new SendOrPostCallback((o) =>
            {
                //执行的代码
            }), null);

Dispatcher 这个对线所有控件都会继承这个,所以你必须要保留主要界面的 Dispatcher ,但我在开发时候,如果使用不当的话会导致界面很卡,大概是代码里面反复调用导致的问题。