System.Runtime.InteropServices.COMException(0x80070008):没有足够的存储空间可用于处理此命令

时间:2010-03-12 19:19:56

标签: .net oracle oracle10g

我正在尝试诊断此异常:

System.Runtime.InteropServices.COMException (0x80070008): Not enough storage is available to process this command. (Exception from HRESULT: 0x80070008)
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType)
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(Type objectType)
at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(Type serverType)
at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(Type serverType, Object[] props, Boolean bNewObj)
at Oracle.DataAccess.Client.CThreadPool..ctor()
at Oracle.DataAccess.Client.OracleCommand.set_CommandTimeout(Int32 value)
...

看起来任何正常类型的“存储”都没有达到任何限制。该应用程序使用大约400MB的内存,70个线程,2000个句柄,硬盘驱动器有许多GB免费。该机器运行Windows 2003 Enterprise Server 32位,内存为16GB,因此内存不应成为问题。

应用程序作为Windows服务运行,因此没有使用GDI对象。耗尽GDI句柄是此异常的常见原因。

数据库连接,命令&所有读者都使用块包装,因此应该正确清理它们。

更新:将我们使用的线程数从12减少到4似乎解决了这个问题。在我们持续4到8小时之前,我们设法在没有错误的情况下运行超过24小时。 UPDATE2:我从来没有弄清楚我们用完了什么资源,但减少线程数似乎已经解决了问题。或至少隐藏它。

3 个答案:

答案 0 :(得分:6)

您需要考虑的另一个因素是内存碎片。

您可以执行的最大单个分配等于进程可用的最大连续内存块。由于碎片,这几乎总是小于进程中可用的内存总量。这是分配在2个空闲内存块之间的内存块“片段”空间。

您在此过程中的碎片越多,可用的最大连续内存块就越小。我已经看到有大约1GB内存可用的情况,但最大的连续块大约是10MB。

您是否在此过程中检查了内存碎片?

答案 1 :(得分:2)

您确实为您的流程消除了此错误的所有明显来源。使其可能实际上是操作系统问题。在服务器上始终处于压力之下的一个资源是内核内存池。很容易看出,TaskMgr.exe在Performance选项卡上显示它。

它有点匹配您的调用堆栈,看起来Oracle提供程序正在为线程池创建线程。一个线程在你的进程中占用一兆字节内核内存池中的24 KB,当线程切换到内核模式时用作堆栈。

背景信息为available here

答案 2 :(得分:0)

看起来某些东西正在循环并在堆上实例化太多对象,因此堆上的内存不足。在调用代码中查找任何循环。