2009-02-03 96 views
3

我正在使用C#和asp.net的Web应用程序工作我一直在收到内存不足的异常。该应用程序的功能是从数据源中读取大量记录(产品),数量可能为数百/数千,通过向导中的设置处理这些记录,然后使用流程产品信息更新不同的数据源。虽然有多个DB类,但现在所有的逻辑都在一个大类中。唯一的原因是所有的信息都与一件产品有关。如果我将应用分成不同的类,它会有助于记忆吗?我不认为这是因为如果我将业务逻辑分为两类,那么两个类都会在整个过程中保持活动状态,因此我不知道这将如何提供帮助。我想我的另一个解决方案是找出吸取所有内存的东西。有没有一个好的工具,你可以推荐?内存不足异常

谢谢

回答

10

您正在使用的DataReader通过您的数据流? (以避免加载太多内存)

我的直觉告诉我,这是一个微不足道的问题,不要将数据表抽成一百万条记录,一次一行地处理表格,或者小批量处理表格。释放和处置对象,当你完成它们。 (例如:没有static List<Customer> allCustomers = AllCustomers()
具有确保没有人读表到内存中是否有比参与行的X量多的发展规律。

如果您需要一个工具来调试这个看.net memory profilerwindbg with the sos extension这两个将允许你嗅探你的托管堆。

另一个需要注意的是,如果您关心可维护性并希望减少您的缺陷数量,请以与您的域更好地对齐的方式正确摆脱SuperDuperDoEverything类和模型信息。 SuperDuperDoEverything类是等待爆炸的炸弹。

1

以Perfmon开头; GC相关信息有很多计数器。很可能你正在泄漏内存(否则GC将会删除对象),这意味着你仍然在引用不再需要的数据结构。

1

你应该分成多个类不管怎么说,只是一个理智设计的缘故。

你关闭你的数据库连接?如果您正在阅读文件,您是否在完成阅读/写作后关闭/释放它们?其他对象也一样。

你可以循环类的对象通常只是来释放内存。

3

你可能想尝试一个很基本的一点是,重新启动Visual Studio(假设你正在使用它),看看同样的事情发生了,是释放对象,而不必等待垃圾回收器始终是一个很好的做法。

概括起来讲,

  • 发行对象
  • 密切联系

,你总是可以试试这个, http://msdn.microsoft.com/en-us/magazine/cc337887.aspx

6

还要注意的是,你实际上可能没有运行内存不足。会发生什么呢。NET转而寻找连续的内存块,如果没有找到任何,它抛出一个OOM - 即使你有足够的总内存的覆盖要求。

有人引用这两个性能监视器和WinDBG中。你也可以设置adplus来捕捉崩溃时的内存转储 - 我相信语法是adplus -crash -iis。一旦你有内存转储,你可以做这样的事情:

.symfix C:\symbols 
.reload 
.loadby sos mscorwks 
!dumpheap -stat 

而这会给你一个你的高内存对象的想法。

当然,请查看Tess Fernandez's优秀的博客,例如本文中的Memory Leaks with XML Serializers以及如何对其进行疑难解答。

如果你能在你的开发环境,瑞普这一点,你有VS团队版开发者,也有内建内存分析器。只要启动一个新的性能会话,并运行你的应用程序。它会吐出一个很好的报告。

最后,确保你的对象不定义析构函数。这不是C++,并没有什么确定的它,除了它保证你的对象将生存一轮垃圾收集,因为它必须放置在终结队列,然后清理了下一轮。

3

我发现这个问题。在做循环时,我有一个没有被清除的集合,所以数据只是不断添加到它。