FileSystemWatcher如何避免在.NET中引发内存碎片化问题?

摘要:一:背景 1. 讲故事 前些天又遇到了一例 FileSystemWatcher 引发的内存碎片化故障,但这个碎片化不是因为经典的 reloadOnChange=true 导致的,所以我觉得有必要做一次深度的反思,供以后遇到类似问题提供技术上
一:背景 1. 讲故事 前些天又遇到了一例 FileSystemWatcher 引发的内存碎片化故障,但这个碎片化不是因为经典的 reloadOnChange=true 导致的,所以我觉得有必要做一次深度的反思,供以后遇到类似问题提供技术上的解决方法,这篇我们就来系统的讲解下 两种碎片化方式的调查方法。 二:经典的 FileSystemWatcher 碎片化 1. 测试代码 这种碎片化是由 reloadOnChange=true 引发的,祸根主要是程序员将 .netframework 读取配置文件的方式套在了 .net 上,为了方便演示,先上一段测试代码。 internal class Program { static void Main(string[] args) { for (int i = 0; i < 100000; i++) { IConfiguration configuration = BuildConfiguration(); string appName = configuration["AppName"]; Console.WriteLine($"i={i} 应用名称: {appName}"); } Console.ReadLine(); } static IConfiguration BuildConfiguration() { return new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); } } 卦中的代码非常简单,就是每次读取 AppName 时都调了一下 BuildConfiguration 方法,仅此而已,但将程序跑起来之后,居然发现程序吃了 2.2G 的内存,真是没边的事,截图如下: 为了找出原因,上 windbg 附加,使用 !dumpheap -stat 观察托管堆,截图如下: 从卦中可以看到两点信息: Free 独占 1.39G,这是经典的内存碎片化。 FileSystemWatcher 高达 1290 个,表明程序存在大量的文件监控。 看到上面两点信息,一定要有条件反射,是不是 reloadOnChange: true 导致的。
阅读全文