悬赏分:50 浏览:535 次
最近发现写得一个服务程序,内存泄露,使得程序不能够7*18小时的运行(晚上0-6点)。
为了解决这个问题,想到了3个办法,请 各位老大帮忙说下可行性:
1:把所有的类都继承IDispose(),并实现资源释放,所有创建的对象都及时设置为null(这个不太能够实现,业务代码很多,使用的线程,事件等等很多,不太可能逐行的查看代码)
2:在写个服务程序,定时重启服务。(这个虽然能够重启服务,但是,占用的内存好像还是不能够一下子释放完)
3:修改原有服务程序,把原有服务程序 的业务代码等,全部放到一个AppDomain里面,定时检查这个AppDomain,并自动释放和创建。(不知道这个方法可以不 ,跪求这样的代码)
也跪求工具,用来查看内存被那些线程,对象等占用。。。
|
所有的类都实现IDisponse并不是个好办法,修改工作量太大了,要显式调用Disponse方法才能释放。 要是重启服务一下都不能释放完的话,是不是线程非后台线程?所以,程序关闭,而线程还在运行。 一般内存占用不释放有几个原因: 1、递归,在递归方法中使用大对象,会造成大对象来不及回收; 2、非托管组件,非托管组件需要自己释放; 3、静态字段; 4、线程驻留,一般是被阻塞了
彻底解决办法还是要查出内存泄漏的原因。 建议用 .NET Memory Profiler 这个工具来跟踪内存使用情况
http://www.cnblogs.com/eaglet/archive/2008/09/05/1285169.html
不要经常创建对象,尽可能的缓存一个对象的副本 CLR Profiler 可以给出详细的信息 1:把所有的类都继承IDispose(),并实现资源释放,所有创建的对象都及时设置为null(这个不太能够实现,业务代码很多,使用的线程,事件等等很多,不太可能逐行的查看代码) 如你所言,不太能够实现,只能督促自己,以后的项目一定要养成使用 using(something) 的好习惯,防止漏网之鱼。指导意义极大。 2:在写个服务程序,定时重启服务。(这个虽然能够重启服务,但是,占用的内存好像还是不能够一下子释放完) 以前和同事也谈过这个,就是定时 kill 某个“进程”,然后启动该程序。模仿人的“关闭”、“启动”行为。我不知道你说的“内容无法释放”是什么意思,"进程"都杀掉了,还能站着茅坑? 3:修改原有服务程序,把原有服务程序 的业务代码等,全部放到一个AppDomain里面,定时检查这个AppDomain,并自动释放和创建。(不知道这个方法可以不 ,跪求这样的代码) 能力不及,看着头晕。会不会是方案 2 的翻版?只不过增加了内存占用等检查措施,而不是一味的“猛杀猛起"。我见过通过 c# 启动 exe 等可执行文件的方法,包括杀死某个进程等。只要方向正确、坚定,手段我看不成问题,google 一下定能搞定! 第一感觉可能是事件导致的。
|
|
3个月前 颜昌钢 : 我也认为大概是事件引起的。。。 也就是 这篇文章说的原因: http://www.cnblogs.com/anders06/archive/2008/01/15/1040123.html 比如有如下的代码: public delegate void TestDelegate(string strTest); public Class Test { public event TestDelegate TestDelegate; protected void OnTestDelegate(string strTest) { if(TestDelegate!=null) { TestDelegate(strTest); } } public void AddStr(string strTest) { OnTestDelegate(strTest); } } public Class Test1 { public void MethodTest() { Test test= new Test(); test.TestDelegate+=new TestDelegate(Test_TestDelegate); test.AddStr("1"); } void Test_TestDelegate(string strTest) { //ToDo: } } 请问,如上的怎么实现 test.TestDelegate-=new TestDelegate(Test_TestDelegate); |
|
3个月前 颜昌钢 : TO:陛下: 2:在写个服务程序,定时重启服务。(这个虽然能够重启服务,但是,占用的内存好像还是不能够一下子释放完) 以前和同事也谈过这个,就是定时 kill 某个“进程”,然后启动该程序。模仿人的“关闭”、“启动”行为。我不知道你说的“内容无法释放”是什么意思,"进程"都杀掉了,还能站着茅坑? 我现在的情况是,在管理工具->服务 里面,选中当前服务,重新启动,内存还是那么大,根本就没有把内存释放。。。(也许我没有在OnStop这个函数里面释放完所有的资源吧。。。。。) 对于第三种,我有查看下MSDN上对于AppDomain的说明,其中有句话: 使用应用程序域隔离可能终止进程的任务。如果正在执行任务的 AppDomain 的状态变得不稳定,则可以卸载 AppDomain,但不会影响进程。当进程必须不重新启动而长时间运行时,这一点很重要。还可使用应用程序域隔离不应共享数据的任务。 似乎可以达到 把所有的业务代码都放到一个AppDomain里面,然后,当内存占用过多,在释放这个AppDomain,然后,再次创建一个。。。。。 |
|
3个月前 陛下 : 有一句成语:“积重难返”,相信兄弟肯定深有感触! |
|
3个月前 颜昌钢 : 哎 看来只有自己慢慢的花时间,把代码全部过一遍了。。。。。 |