Delphi:系统错误1158的原因(当前进程没有更多系统句柄)

时间:2011-02-11 08:19:29

标签: multithreading delphi

将应用程序闲置很长一段时间后,当我点击表单时,它通常会崩溃。

我每天都要闲着,看看我是否发现了这个错误,最后今天早上我开始使用它,经过几次点击后我得到了:

系统错误1158当前进程已使用其所有系统容差处理

所以不知怎的,我使用了所有的资源,幸运的是今天早上我开始使用应用程序几乎没有资源,我使用它直到所有句柄都不再可用。在所有其他日子里,我来不及,没有更多的手柄(这是我怀疑的)。当然,在这种情况下,应用程序在我点击它时崩溃了。

现在你能建议一个解决方案吗?我使用线程定期检查新消息或计算有多少用户在线。但我仔细检查了一下,我在每个线程之后释放了一切。 (但可能还有一些我不了解的关于线程的东西)。应用程序始终连接到数据库(我使用DevArt SDAC),无论如何都没有断开连接,因为如果断开连接,我会收到警告,并提示用户尝试重新连接。

3 个答案:

答案 0 :(得分:6)

您可以使用GetProcessHandleCount函数编写一个函数来监视应用程序的打开句柄,然后调试应用程序并使用OutputDebugString之类的内容显示结果。

uses
  Windows,
  SysUtils;

function GetProcessHandleCount(hProcess: THandle; var pdwHandleCount: DWORD): BOOL;  stdcall; external 'Kernel32.dll' name 'GetProcessHandleCount';

function GetOpenHandles : DWORD;
begin
 if not GetProcessHandleCount(GetCurrentProcess,Result) then
     RaiseLastOSError;
end;

使用像这样的

 OutputDebugString(PAnsiChar(IntToStr(GetOpenHandles)));
 Task1;
 OutputDebugString(PAnsiChar(IntToStr(GetOpenHandles)));
 Task2;
 OutputDebugString(PAnsiChar(IntToStr(GetOpenHandles)));
 Task3;
 OutputDebugString(PAnsiChar(IntToStr(GetOpenHandles)));

答案 1 :(得分:3)

如果你的手柄用完了,那只能意味着一件事:你正在分配它们而不是释放它们。在完全调试模式下使用FastMM内存管理器等工具,为您提供有关未被释放内容的更多信息。

为了避免这种情况,在开发时应始终以完全调试模式使用内存管理器...

更新 据我所知,FastMM确实报告了内存泄漏而不是资源处理泄漏。检测句柄泄漏的最佳方法似乎是与Windows本身捆绑在一起的PerfMon工具:http://www.codeguru.com/cpp/v-s/debug/memoryissues/article.php/c4411

可以在MSDN上找到如何使用PerfMon工具的示例:http://msdn.microsoft.com/en-us/library/aa645516(v=vs.71).aspx

答案 2 :(得分:2)

你肯定是在某处泄漏手柄。您是否使用任务管理器监控句柄使用情况这可能会为您提供泄漏发生时间的线索。

尝试禁用应用程序的某些部分以查看泄漏发生的时间以及何时不发生泄漏,因此您可以缩小问题范围。