记录由Equal基础知识引起的内存泄露

在使用第三方反射缓存库时遇到内存泄露问题,通过排查发现缓存对象未正确重写Equal方法导致内存占用异常增高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      在最近的公司框架开发中,利用了网上某大牛的反射缓存库作为辅助。在测试的时候发现出现了巨大的内存泄露,在频繁的操作后,内存不断的产生巨大的开销,10多分钟就占有了5,6m的内存。解决问题的时,公司不能上网,没有内存分析工具,没有我钟爱的ANTS Memory Profiler帮助下,我们只能靠简单的内存输出来二分查找缩小范围,利用

System.Diagnostics命名空间下的Process的WorkingSet64属性来统计两次输出的内存增长量(WorkingSet64:描述关联的进程分配的物理内存量(以字节为单位))。花了半天终于定位到了第三方的缓存块,一看吓一跳居然缓存了2,3万的对象。看到这里我很清楚的猜测到自定义缓存key一定没有重写来自Object的Equal方法,在三两下很快解决了这次问题。哎,本不该相信第三方,刚开始还以为我数据绑定注册的一大堆客户端控件的事件引起的,但是我实现了IDisposable并取消了事件的,必究事件代理是强类型引用。

    在这里我简单说说这个本是基础知识的东西。说道Equal,我们会联想到==操作符,==对于值类型表示的是值相等,除string类型(内部重写)外表示的是对象的引用,同一个引用地址才会相等。Equal描述的是对象的内容是否相等。但是在Object中默认实现是对引用reference的比较,我们要实现值的比较这必须重写Equal方法和GetHashCode方法,这两个是同时重写的。在我们的IList.Contains,IDictionary.Contains中利用对象的比较就是默认的Equal方法比较,所以我们必须重写这个方法,来达到我们实际的值比较。MSDN:Equals() 和运算符 == 的重写准则(C# 编程指南)

   然而在我们3.0后的表达式linq中对于对象的比较,我们需要实现的IEqualityComparer<T>接口,如下定义:

public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer);

在微软内部实现了5个重要的类,如下图(图来自博客园鹤冲天大牛):

image

在这里我不想在说很多,关于可以参见博客园鹤冲天大牛的c# 扩展方法奇思妙用基础篇八:Distinct 扩展何止 Linq 的 Distinct 不给力文章实战。

最后给初学者提醒一句,对于IList.Contains,IDictionary.Contains注意实现Equal和GetHashCode,Linq比较IEqualityComparer<TSource>。

本不该错的,应该是大牛忘写了吧,可是害惨了我。


作者:破  狼 
出处:http://www.cnblogs.com/whitewolf/ 
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼。http://www.cnblogs.com/whitewolf/archive/2011/12/30/2307894.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值