我遇到一个问题,我的.NET 3.5应用程序导致IIS工作进程不断耗尽内存并且永远不会释放它,直到应用程序开始抛出与内存相关的错误并且我必须回收IIS工作进程。我注意到的另一件事是,与Oracle数据库服务器的连接也没有关闭,并且在我回收IIS工作进程之前一直保持打开状态(据我所知,我关闭了Oracle连接正确)。根据我在其他类似帖子中读到的内容,GC应该清理未使用的内存并允许重新分配,但这显然不会发生在这里(我在远程主机上观察到同样的问题)和本地主持人。我会假设这不是与IIS设置有关的问题,而是我在代码中没有做适当的清理工作;我应该看一下什么?谢谢
以下是与查询Oracle DB相关的代码:
Using conn As New OracleConnection(oradb)
Try
cmd.Connection = conn
daData = New OracleDataAdapter(cmd)
cbData = New OracleCommandBuilder(daData)
dtData = New DataTable()
dtDADPLIs = New DataTable()
conn.Open()
cmd.CommandText = "SELECT * FROM TABLE" _
daData.Fill(dtData)
cmd.CommandText = "SELECT * FROM TABLE2"
daData.Fill(dtDADPLIs)
QueryName = "SD_TIER_REPORT"
WriteQueryLog(QueryName)
Catch ex As OracleException
'MessageBox.Show(ex.Message.ToString())
Finally
conn.Close()
conn.Dispose()
End Try
答案 0 :(得分:1)
一旦遇到同样的问题,我就碰到了这个article和one。 我与作者(保罗·威尔逊)交换了几封电子邮件,他帮助我理解了大型对象的问题,这些对象在“大对象堆”的内存中分配,并且永远不会被压缩。
这是他告诉我的:
较大的对象确实是分开分配的,其中大的是 约60-90 KB或更大的东西(我不记得确切,它的 无论如何都没有正式记录)。所以如果你的字节数组,和其他 对于这个问题,对象大于那个阈值然后他们会 分开分配。什么时候大对象堆得到 集?你可能已经遇到过关于有几个的陈述 几代正常的内存分配(当前为0,1和2) 框架) - 基本上考虑大对象堆 自动成为第2代。这意味着它不会 收集,直到收集第0代后没有足够的内存 和gen 1 - 所以基本上它只发生在一个完整的GC集合上。所以 回答你的问题 - 没有办法确定对象 大型对象堆更快收集。问题是我是 谈论垃圾收集,它假定你的对象 (在这种情况下,大对象)不再在任何地方引用 因此可以收集。如果他们仍然被引用 在某个地方,那么GC的运行程度无关紧要 - 你的 内存使用量只会上升。那么你有所有 参考没了?看起来你可能会这么做,你可能是对的 - 我所有人 可以告诉你的是它很容易出错,而且它很可怕 内存分析器的工作量,没有快捷方式来证明它 方式或其他。我可以告诉你,如果手动GC.Collect可靠 确实减少了你的内存使用量,然后你显然得到了你的对象 取消引用 - 否则GC.Collect无济于事。所以问题可能是 只是让你认为你有记忆问题的原因?那里 如果你有足够的GC可能没有理由收集内存 可在大型服务器系统上使用!
另一篇值得一读的文章是this。
解决方案?
更新:
如果您使用报告工具,例如 MS ReportViewer ,则可以将报告绑定到“业务对象”。