gpt4 book ai didi

delphi - 如何追踪内存不足异常?

转载 作者:行者123 更新时间:2023-12-03 15:57:01 26 4
gpt4 key购买 nike

堆栈看起来像这样

:7576b9bc KERNELBASE.RaiseException + 0x58
:671c57ad ; F:\invariant data - not DropBox\3rd_party_vcl\MAD collection\madExcept\Dlls\madExcept32.dll
:671c953f ; F:\invariant data - not DropBox\3rd_party_vcl\MAD collection\madExcept\Dlls\madExcept32.dll
:71a80013
System._ReallocMem(???,???)
:0040497d @ReallocMem + $45
System._DynArraySetLength
IdIOHandler.TIdIOHandler.ReadFromSource(True,-2,True)
IdIOHandler.TIdIOHandler.ReadLn(#$A,-1,16384,$D3B6FF0)
IdIOHandler.TIdIOHandler.ReadLn(nil)
IdCmdTCPServer.TIdCmdTCPServer.ReadCommandLine($7CC1AFB4)
IdCmdTCPServer.TIdCmdTCPServer.DoExecute($7CC1AFB4)
IdContext.TIdContext.Run
IdTask.TIdTask.DoRun
IdThread.TIdThreadWithTask.Run
IdThread.TIdThread.Execute
:004ccf91 HookedTThreadExecute + $2D
System.Classes.ThreadProc($7A486F84)
System.ThreadWrapper($7BFBEFF8)
:004cce73 CallThreadProcSafe + $F
:004ccee0 ThreadExceptFrame + $3C
:7559339a kernel32.BaseThreadInitThunk + 0x12
:76f39ef2 ntdll.RtlInitializeExceptionChain + 0x63
:76f39ec5 ntdll.RtlInitializeExceptionChain + 0x36

这些都不是我的代码。它看起来像 INDY 代码,但我意识到,如果我的代码有错误,那么由于我占用了所有内存,异常仍然可以在其他地方抛出。

我正在运行 MAD except 并打开泄漏检测。如果我运行一段时间并关闭程序,它会报告没有泄漏。如果我让程序运行几个小时,就会出现内存不足的异常。

我只调用了两次 Create(),两者都在计时器处理程序中,并且我已将计时器持续时间设置为一秒以进行测试。处理程序非常简单,并且始终 Free() 创建的对象。

除了计时器处理程序的代码之外,还有什么我可以看的吗?

如果有人真的需要查看它,这里是代码...这是我 Create() 对象的唯一两个地方...

procedure TMainForm.ServerAliveTimerTimer(Sender: TObject);

var timestamp : LongInt;
ADConnection: TADConnection;
theDialogForm : TDialogFormForm;
begin
ServerAliveTimer.Enabled := False;
TraceInfo('ServerAliveTimer expired after ' + IntToStr(ServerAliveTimer.Interval div 1000) + ' seconds');

try
ADConnection := TADConnection.Create(Self);
ADConnection.DriverName := 'mysql';
ADConnection.Params.Add('Server=' + MAIN_STOREROOM_IP_ADDRESS);
ADConnection.Params.Add('Database=XXX');
ADConnection.Params.Add('User_Name=XXX');
ADConnection.Params.Add('Password=XXX');
ADConnection.Params.Add('Port=3306');
ADConnection.Connected := True;

except
on E : Exception do
begin
StopAllTimers();

TraceError('Database error. Failed to create ADO connection');

ADConnection.Free();

theDialogForm := TDialogFormForm.Create(Nil);
theDialogForm.ShowTheForm('Database problem'+#13+#10+''+#13+#10+
E.ClassName+#13+#10+
E.Message);

StopTheApplication();
Exit;
end;
end;

if isMainStoreRoom then
begin
CheckIfStoreRoomIsAlive(SECONDARY_STOREROOM_IP_ADDRESS);
end
else
begin
CheckIfStoreRoomIsAlive(MAIN_STOREROOM_IP_ADDRESS);
end;

// Now, update our own timestamp
try
timestamp := GetCurrentUnixTimeStamp();
ADConnection.ExecSQL('UPDATE server_status SET alive_timestamp="' + IntToStr(timestamp) + '" WHERE ip_address="' + ipAddress + '"');

except
on E : Exception do
begin
TraceError('Database error. Failed to upate timestamp for ip_address = "' +
ipAddress + ' in table "server_status"' + #13#10#13#10 +
E.ClassName+#13+#10+
E.Message);
ADConnection.Free();
Exit;
end;
end;

ADConnection.Free();
ServerAliveTimer.Enabled := True;
end; // ServerAliveTimerTimer()

procedure TMainForm.CheckEndOfScheduleTimerTimer(Sender: TObject);
var ADConnection : TADConnection;
ADQuery : TADQuery;
secondsSinceMidnight : LongInt;
timeNow : LongInt;
today : LongInt;
checkoutDay : LongInt;
checkoutExpireTime : LongInt;
theDialogForm : TDialogFormForm;
rfidTag : String;
i : integer;
begin
CheckEndOfScheduleTimer.Enabled := False;

ADConnection := Nil;
ADQuery := Nil;

try
TraceInfo('CheckEndOfScheduleTimer expired after ' + IntToStr(CheckEndOfScheduleTimer.Interval div 1000) + ' seconds');

secondsSinceMidnight := GetSecondsSinceMidnight();
timeNow := GetCurrentUnixTimeStamp();
today := timeNow - secondsSinceMidnight;

ADConnection := TADConnection.Create(nil);
ADConnection.DriverName := 'mysql';
ADConnection.Params.Add('Server=' + MAIN_STOREROOM_IP_ADDRESS);
ADConnection.Params.Add('Database=XXX');
ADConnection.Params.Add('User_Name=XXX');
ADConnection.Params.Add('Password=XXX');
ADConnection.Params.Add('Port=3306');
ADConnection.Connected := True;

ADQuery := TADQuery.Create(ADConnection);
ADQuery.Connection := ADConnection;
ADQuery.Open('SELECT * FROM tagged_chemicals');
ADQuery.FetchAll();

for i := 0 to Pred(ADQuery.Table.Rows.Count) do
begin
if ADQuery.Table.Rows[i].GetData('checked_out') = 'N' then
Continue;

checkoutDay := ADQuery.Table.Rows[i].GetData('checkout_day');
checkoutExpireTime := ADQuery.Table.Rows[i].GetData('checkout_expire_time');

if (today + secondsSinceMidnight) > (checkoutDay + checkoutExpireTime) then
begin
rfidTag := ADQuery.Table.Rows[i].GetData('rfid_tag');

TraceInfo('End of pouring time for RFID tag (' + IntToStr(secondsSinceMidnight) + ' seconds after midnight');

ADConnection.ExecSQL('UPDATE tagged_chemicals ' +
'SET checked_out="N", ' +
'checkout_day="0", ' +
'checkout_expire_time="0" ' +
' WHERE rfid_tag="' + rfidTag + '"');
end;
end;

ADQuery.Free();
ADConnection.Free();

except
On E: Exception do
begin
ADQuery.Free();
ADConnection.Free();
TraceError('Databse exception (' + E.ClassName + ') : "' + E.Message + '"');

theDialogForm := TDialogFormForm.Create(Nil);
theDialogForm.ShowTheForm('Database error when checking end of pouring time'+#13+#10+''+#13+#10+
E.ClassName+#13+#10+
E.Message);
end;
end;

CheckEndOfScheduleTimer.Enabled := True;
end; // CheckEndOfScheduleTimerTimer()

最佳答案

尝试使用Sysinternals工具 VMMap 和 Process Explorer 这应该告诉您内存的去向。

关于delphi - 如何追踪内存不足异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12582787/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com