Kev*_*lin 14 .net regex memory-leaks
我最近在WinForms应用程序中查看了一些.NET"内存泄漏"(即意外的,挥之不去的GC根源对象).在加载然后关闭一个巨大的报告之后,即使在几个gen2集合之后,内存使用量也没有像预期的那样下降.假设报告控件被一个迷路事件处理程序保持活着,我破解了打开WinDbg以查看发生了什么......
使用WinDbg,该!dumpheap -stat命令报告了字符串实例消耗了大量内存.使用!dumpheap -type System.String命令进一步完善了这一点,我找到了罪魁祸首,一个用于报告的90MB字符串,地址为03be7930.最后一步是调用!gcroot 03be7930以查看哪些对象保持活着状态.
我的期望是不正确的 - 它不是一个悬挂在报告控件(和报告字符串)上的非挂钩事件处理程序,而是由一个System.Text.RegularExpressions.RegexInterpreter实例保留,该实例本身是一个的后代System.Text.RegularExpressions.CachedCodeEntry.现在,Regexs的缓存(有点)是常识,因为这有助于减少每次使用时重新编译Regex的开销.但是,这与保持我的弦活着有什么关系呢?
基于使用Reflector的分析,事实证明只要调用Regex方法,输入字符串就存储在RegexInterpreter中.RegexInterpreter保留此字符串引用,直到通过后续Regex方法调用将新字符串输入其中.我希望通过挂在Regex.Match实例上以及其他可能的类似行为.链是这样的:
违规的Regex仅用于报告,很少使用,因此不太可能再次用于清除现有的报告字符串.即使后来使用正则表达式,也可能会处理另一份大型报告.这是一个相对重要的问题,只是简单的感觉很脏.
总而言之,我找到了一些关于如何解决或至少解决这种情况的选项.我会先让社区回复,如果没有人提出来,我会在一两天内填补空缺.