我正在使用C#和asp.net开发一个Web应用程序我一直在收到内存不足异常。该应用程序所做的是从数据源读取一堆记录(产品),可能是数百/数千,通过向导中的设置处理这些记录,然后使用流程产品信息更新不同的数据源。虽然有多个DB类,但现在所有逻辑都在一个大类中。唯一的原因是,所有信息都与一件产品有关。如果我将我的应用程序划分为不同的类,它会帮助记忆吗?我认为不会这样,因为如果我将业务逻辑划分为两个类,那么这两个类在整个发送消息时都会保持活跃状态,所以我不知道这会有什么帮助。我想我的另一个解决方案是找出吸收所有内存的东西。你有没有推荐的好工具?
由于
答案 0 :(得分:10)
您是否正在使用数据加载器来传输数据? (避免在内存中加载太多)
我的直觉告诉我这是一个微不足道的问题需要解决,不要为100万条记录泵送数据表,一次一行地处理表格,或者小批量处理......完成后释放并处理对象跟他们。 (例如:没有static List<Customer> allCustomers = AllCustomers()
)
有一个开发规则,如果涉及的行数超过X,则确保没有人将表读入内存。
如果你需要一个工具来调试这个.net memory profiler或windbg with the sos extension,那么两者都可以让你嗅探你的托管堆。
另一个注意事项是,如果您关心可维护性并希望减少缺陷数量,请以更好地与您的域对齐的方式正确删除SuperDuperDoEverything类和模型信息。 SuperDuperDoEverything类是一个等待爆炸的炸弹。
答案 1 :(得分:6)
另请注意,您实际上可能没有内存不足。会发生什么是.NET去寻找连续的内存块,如果找不到,它会抛出一个OOM - 即使你有足够的总内存来覆盖请求。
有人引用了Perfmon和WinDBG。您还可以设置adplus以在崩溃时捕获内存转储 - 我相信语法为adplus -crash -iis
。进行内存转储后,您可以执行以下操作:
.symfix C:\symbols
.reload
.loadby sos mscorwks
!dumpheap -stat
这将让您了解高内存对象是什么。
当然,请查看Tess Fernandez's优秀博客,例如Memory Leaks with XML Serializers上的这篇文章以及如何对其进行问题排查。
如果您能够在您的开发环境中重新启动它,并且您拥有VS Team Edition for Developers,则可以内置内存分析器。只需启动一个新的性能会话,然后运行您的应用。它会吐出一个很好的报告。
最后,确保您的对象没有定义析构函数。这不是C ++,并且没有任何确定性,除了它保证你的对象将在一轮垃圾收集中存活,因为它必须被放置在终结器队列中,然后清理下一轮。
答案 2 :(得分:3)
你可能想要尝试的一个非常基本的事情是,重新启动visual studio(假设你正在使用它)并查看是否发生了同样的事情,并且在不等待垃圾收集器的情况下释放对象总是一个好习惯。
总结一下,
你可以随时试试这个, http://msdn.microsoft.com/en-us/magazine/cc337887.aspx
答案 3 :(得分:3)
我发现了问题。在做我的循环时,我有一个未被清除的集合,因此数据只是被添加到它。
答案 4 :(得分:1)
从Perfmon开始; GC相关信息有许多计数器。你很可能泄漏了内存(否则GC会删除对象),这意味着你仍然在引用不再需要的数据结构。
答案 5 :(得分:1)
无论如何,你应该分成多个类,只是出于理智的设计。
您是否关闭了数据库连接?如果您正在阅读文件,那么一旦您完成阅读/写作,您是在关闭/发布它们吗?其他对象也是如此。
您可以定期循环您的类对象以释放内存。