今天探讨一个技术问题吧,c#内存溢出错误,即system.outofmemoryexception
最近一直在研究海量数据采集及智能化数据识别的问题。由此引发了内存溢出。因为是多线程系统,对内存溢出的判断不是很好进行,采用了很多方法来进行,总结一下:
1、首先检查代码,尤其是那些循环的操作;避免使用while(true),如果必须使用,则一定要完善退出循环的问题;
2、检查资源的释放,使用完资源必须释放;需要深入了解IDisposable,同时需要深入了解什么是托管资源,什么是非托管资源;
3、多线程程序,做好同步操作;避免出现资源争夺;
以上三点做到,还是内存溢出,报system.outofmemoryexception 错误,则可使用工具进行跟踪内存占用情况,推荐工具为:CLRProfiler
此时注意了,如果使用了正则匹配,那么要小心了,微软提供的正则表达式,有个两个严重的问题,
1、不报错,但也不响应;
2、不报错,内存耗尽;
两个问题都很致命,测试过正则,应该是产生了无休止的匹配,实际也未必是无休止,只不过匹配一直没有结束而已,优秀的方法是优化正则表达式,或者进行分层匹配。但如果是在无法避免正则表达式的质量,则可以通过异步的方法来调用正则匹配,并通过waitone设置等待时间,超时,则强制结束。但此种方法在一定程度上还是无法避免内存溢出,如果是单线程,应该就放心了,如果是多线程系统,则此种情况至少现在我还没有找到一个理想的方法。我当前是做了一个资源控制器,来协调线程工作,当资源超出预设阀值,则自动暂停一部分线程工作,并开始等待,等资源恢复正常,即将等待线程进行恢复。另外,一定要注意system.outofmemoryexception的来源,如果是正则匹配内存溢出,一般是system.outofmemoryexception来自mscorlib,此为程序集,查资料说是mscorlib并未对正则表达式内存溢出错误做控制。
.net程序对内存占用的测试,win32程序单进程最大可使用2GB内存,测试.net程序可最大使用1.3GB内存,在win2003+sp2环境下,在至强4核8线程,8GB内存的服务器环境下,开启 PAE和3GB的情况下,测试可占用1.6GB内存,再大就报内存溢出了,同时使用editbin进行设置,也未见效果,可能是方法有误吧,与网上所讲可使用2.4GB相差甚远啊。如果真的要消耗内存,建议直接上64位吧,别折腾了。
原本以为list<T>较为占用内存,但通过实际测试,发现list<T>占用内存应该还算合理,有点误区,测试的是list<String>和string[]的比较,结果list<T>胜出。
GC.Collect不会立即回收内存,相反,如果频繁调用则也会消耗资源。
多线程程序,需要控制线程执行的效率,同样的多线程程序,在不同机器中可测试出不同的错误,此应该是线程执行效率加快所带来的负面问题,在做好资源同步之后,还要考虑线程等待和执行的问题。
基本就说这么多,都是一些空洞的东西,也许对解决实际问题帮助不大。