【问题标题】:Worker process not releasing memory and Oracle connection not closing工作进程未释放内存且 Oracle 连接未关闭
【发布时间】:2013-09-10 12:09:39
【问题描述】:

我有一个问题,我的 .NET 3.5 应用程序导致 IIS 工作进程不断消耗内存并且在应用程序开始抛出与内存相关的错误之前永远不会释放它,我必须回收 IIS 工作进程。我注意到的另一件事是,与 Oracle DB 服务器的连接也不会关闭,并且会保持打开状态,直到我回收 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

【问题讨论】:

  • 您是否在应用程序中实现using(OracleConnection cn = new OracleConnection()) {...} 语法糖以在连接对象关闭后对其进行处置?你能告诉我们你的代码通常是如何打开一个连接然后关闭/处理它的吗?
  • 另外,在问这样的问题时,您能否指定 Windows/IIS 版本以及与您的应用程序池配置相关的位置。
  • 我正在使用带有 IIS 5.1 的 Windows XP。我在下面添加了 Oracle 连接代码
  • @StephenT:你为什么不用这段代码更新你的问题?
  • 我可以看到您正在使用数据表。你打算读多少条记录?缓冲区大吗?

标签: vb.net oracle iis


【解决方案1】:

当我遇到同样的问题时,我碰到了这个article 和这个one
我与作者(Paul Wilson)交换了几封电子邮件,他帮助我理解了在“Large Object Heap”内存中分配的大型对象的问题,并且它永远不会被压缩。

这是他告诉我的:

较大的对象确实是单独分配的,其中大的 大约 60-90 KB 或更大的东西(我记不太清了,它的 无论如何都没有正式记录)。因此,如果您的字节数组和其他 就此而言,物体大于该阈值,那么它们将 分开分配。大对象堆什么时候拿到 集?你可能遇到过关于有几个 代正常内存分配(当前的 0、1 和 2 框架)——好吧,大对象堆基本上被认为是 自动成为第 2 代。这意味着它不会 收集到 gen 0 后没有足够的内存 和 gen 1 - 所以基本上它只发生在完整的 GC 集合上。所以 回答你的问题——没有办法确保 大对象堆被尽快收集。问题是我在 谈论垃圾收集,它假设你的对象 (在这种情况下为大对象)不再在任何地方引用,并且 因此可以收集。如果它们仍然被引用 在某个地方,那么 GC 运行多少就无关紧要了——你的 内存使用量只会越来越高。所以你有吗 参考资料没了?看起来你这样做了,你可能是对的——我只是 可以告诉你的是,它很容易出错,而且很糟糕 使用内存分析器进行大量工作,并且没有捷径可以证明这一点 方式或其他。我可以告诉你,如果手动 GC.Collect 可靠 确实减少了你的内存使用,那么你显然得到了你的对象 取消引用——否则 GC.Collect 将无济于事。所以这个问题可能 仅仅是什么让你认为你有记忆问题?那里 如果你有足够的内存,GC 可能没有理由收集内存 在大型服务器系统上可用!

另一篇值得一读的文章是this

解决方案?

  1. 只获取您需要的数据
  2. 尽可能避免使用数据集并选择数据读取器。

更新:

如果您正在使用像 MS ReportViewer 这样的报告工具,如果您可以将报告绑定到“业务对象”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-03
    • 2018-12-09
    • 1970-01-01
    • 2013-07-18
    • 2019-02-01
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    相关资源
    最近更新 更多