一:背景 前两篇我们都聊到了非托管内存泄漏,一个是 HeapAlloc ,一个是 VirtualAlloc,除了这两种泄漏之外还存在其他渠道的内存泄漏,比如程序集泄漏,这一篇我们就来聊一聊. 二: 程序集也会泄漏? 在我分析的一百多dump中,程序集方面的泄漏主要有 XmlSerializer 和 Castle.Proxy 这两个入口,这里就来探讨 XmlSerializer 所造成的泄漏. 1. 问题代码 为了方便讲述,先上一段测试代码,百分百内存泄漏,如假包换. internal class…
一:背景 去年 GC架构师 Maoni 在 (2021 .NET 开发者大会) [https://ke.segmentfault.com/course/1650000041122988/section/1500000041123017] 上演示过 PerfView 的 Diff 功能来寻找内存增量,个人感觉这个功能非常不错,简单省事,所以这里就整合到 PerfView 专题中,分享一下给大家. 二:洞察内存增量 1. 什么是内存增量 其实非常好理解,就是当你的程序出现了内存泄漏,你可以在程序内存…
一:背景 上一篇我们聊到了如何用 PerfView 去侦察 NTHeap 的内存泄漏,这种内存泄漏往往是用 C 的 malloc 或者 C++ 的 new 分配而不释放所造成的,这一篇我们来聊一下由 VirtualAlloc 方法造成的泄漏如何去甄别? 了解 VirtualAlloc 的朋友肯定说, C# 这种高层语言怎么可能会用 VirtualAlloc 呢?即便是 C++ 大概率也不会用这个,其实这么说还是世面见少了,经历的案例太少,接下来我们就来简要聊一聊. 二: C# 中真的会用 Vir…
一:背景 前几篇我们聊的都是 非托管内存泄漏,这一篇我们再看下如何用 PerfView 来排查 托管内存泄漏 ,其实 托管内存泄漏 比较好排查,尤其是用 WinDbg,毕竟C#是带有丰富的元数据,不像C++下去就是二进制. 二:如何分析 PerfView 用的是权重占比来寻找可疑的问题函数,为了方便讲述,我们先上一段问题代码. internal class Program { static void Main(string[] args) { Task.Run(Alloc1); Task.Run…
一:背景 这篇我们来聊一下 PerfView 在协助 WinDbg 分析 Dump 过程中的两个超实用技巧,可能会帮助我们快速定位最后的问题,主要有如下两块: 洞察内存泄漏中的静态大集合变量名. 验证当前程序的 GC 模式. 这里就把经验分享一下,希望让大家少走弯路. 二:如何洞察 1. 查看静态变量名 如果有过 dump 分析经验的朋友应该知道,当你历经千辛万苦在 内存泄漏 的dump文件中找到了那个内存泄漏最大的集合,但遗憾的是,你不知道这个 集合 的变量名叫什么? 为了方便讲述,先上一段测…
一:背景 在洞察 GC 方面,我觉得市面上没有任何一款工具可以和 PerfView 相提并论,这也是为什么我会在 WinDbg 之外还要学习这么一款工具的原因,这篇我们先简单聊聊 PerfView 到底能洞察 GC 什么东西? 二:洞察 GC 1. 到底都能看到 GC 什么? 能获取到的 GC 信息非常多,比如: 程序运行期间 GC 触发了多少次? GC 最大一次暂停耗费了多久? 每一次 GC 触发的原因是什么? GC 暂停 >200ms 的都有哪些? GC 触发 3 阶段中各个函数的耗时是怎样…
一:背景 上一篇我们聊到了如何用 PerfView 洞察 GC 的变化,但总感觉还缺了点什么? 对,就是要跟踪到底是什么代码触发了 GC,这对我们分析由于 GC 导致的 CPU 爆高有非常大的参考价值,在以前我都是用 WinDBG 来实现,但这玩意需要做一些侵入性操作,实战起来不是那么丝滑,虽然有可以录制功能的 TTD,所以需寻找完美的解决方案,在此可以借助一下 PerfView . 二:如何洞察 1. 一个小案例 为了方便讲解,先上一段简单的测试代码,不断的往 List 中塞入数据,可以实现不…
一:背景 C# 程序内存泄漏的诱发因素有很多,但从顶层原理上来说,就是该销毁的 用户根 对象没有被销毁,从而导致内存中意料之外的对象无限堆积,导致内存暴涨,最终崩溃,这其中的一个用户根就是 终结器队列,这一篇我们就来看下如何让 PerfView 配合 WinDbg 双剑合璧. 二:如何洞察 1. 终结器内存泄漏 为了模拟 终结器内存泄漏,我们故意在 析构函数 中执行复杂的逻辑,让析构过程足够的慢,这样可以实现 分配速度 远大于 销毁速度 ,达到消费能力不足引发的内存暴涨, 参考如下代码: int…
在之前的文章中,我们使用的都是持久连接,但是使用持久连接的话,这种模拟socket的形式使用起来还是很不方便的,比如只有一个唯一的 OnReceived方法来处理业务逻辑,如下图: protected override Task OnReceived(IRequest request, string connectionId, string data) { return Connection.Broadcast(data); } 但是在singlaR体系中并不是这样,我们还有更加平易近人的一个类…
概述 异步通知是客户端开发中常见的需求,比如在一个网络处理线程中要通知UI线程更新等等. 通常在Windows编程中,为了方便,我们一般会向UI线程的窗口句柄Post/Send一个窗口消息从而达到将非UI线程的事件切换到UI线程处理的目的. 在SOUI引入通知中心以前要在SOUI中处理非UI线程事件我也推荐用上面的方法. 使用窗口消息至少有以下两个不足: 1.需要在线程中持有一个窗口句柄. 2.发出的消息只能在该窗口句柄的消息处理函数里处理. SNotifyCenter 最新的SOUI引入了一个…