[fix]降低RedisCacheProvider对IConfigProvider的依赖,在外部没有注册IConfigProvider时(常见于没有星尘),自动加载本地配置文件。
大石头 编写于 2024-10-31 09:19:20
NewLife.Redis
# dotMemory分析Redis的GC分配 ​ NewLife组件进入v11时代,重点是减少内存GC。NewLife.Redis作为第一站试用,目标是Redis指令收发过程中,减少内存分配,降低GC。 ​ 本文对基础要求很高,假定你熟悉dotMemory并阅读过NewLife.Redis源代码。 ## 改进前分析 ​ Test测试项目改为Test2,启用Bench压测。该压测会执行数百万次Redis操作,可以观测到大量GC。 ​ 直接查看内存分配: ![image-20240826230046519](/NewLife/NewLife.Redis/Blob/master/Doc/dotMemory分析Redis的GC分配.assets/image-20240826230046519.png) ​ 得知内存分配最多的是这里: ![image-20240826230118528](/NewLife/NewLife.Redis/Blob/master/Doc/dotMemory分析Redis的GC分配.assets/image-20240826230118528.png) ​ 由此得知,我们需要优化GetResponse,让它使用内存池。当然,在那之前,我们先关闭缓冲流BufferedStream。 ## 去掉缓冲流 ​ 去掉缓冲流,再次测试。Byte[]的内存分配竟然从2.53G下降到905M,看样子它的设计并不好。 ![image-20240826230614166](/NewLife/NewLife.Redis/Blob/master/Doc/dotMemory分析Redis的GC分配.assets/image-20240826230614166.png) ​ 至此,可以发现,最大内存消耗来自于Encode,也就是把参数转为字节数组的环节。 ## 优化Encode ​ 采用Span优化Encode,对于字符串,直接编码转换,避免再次分配字节数组。 ![image-20240827021401420](/NewLife/NewLife.Redis/Blob/master/Doc/dotMemory分析Redis的GC分配.assets/image-20240827021401420.png) ​ 字节数组分配降到772M,现在的问题是,无法准确估算缓冲区大小,导致借出内存过大,产生LOH分配。 ## 完全Encode参数 ​ 执行命令前,先把参数Encode编码为字符串或字节数组,方便Span写入。其实绝大部分场景都是字符串。Byte[]分配下降到263M。 ![image-20240827112839799](/NewLife/NewLife.Redis/Blob/master/Doc/dotMemory分析Redis的GC分配.assets/image-20240827112839799.png)