Delphi: How to find and fix EOutOfMemory error?

I am creating a delphi application that does scientific modeling. It grows in complexity and now consists of many units and forms.

I run EOutOFMemory Errors every time I start. It seems that this happens during or immediately after I temporarily used the Array option as part of the functions. There is a risk of asking a really stupid question, are there "many options" that require trouble? (I could convert everything to a string, but an array of options basically saves a lot of fancy stuff).

using a forbid array can be:

Function TProject.GetCurrentProjParamsAsArray(LProjectName, LProjectType : ShortString): ArrayOfVariant; Var ArrayIndex : Word; begin SetLength (Result,54); ArrayIndex := 0; Result [ArrayIndex] := LProjectName; Inc(ArrayIndex); Result [ArrayIndex] := LProjectType; Inc(ArrayIndex); // this structure makes it easier to add extra fields in the DB than hard coding the array index!! Result [ArrayIndex] := FileTool.DateTimeForFileNames ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. SiteName ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. PostCode ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. MetFileNamePath ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. SiteLat ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. SiteLong ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. SiteAlt ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. TZoneIndex ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. TZoneHours ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. TZoneMeridian ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. Albedo ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. ArrayTilt ; Inc(ArrayIndex); Result [ArrayIndex] := SiteAndMet. ArrayAzimuth ; Inc(ArrayIndex); 

In the task manager, peak memory usage is 42 MB, VM is 31M, and I get ~ 90,000 page errors for every run. (on an xp machine with 3 GB of RAM)

Does anyone have general tips on monitoring memory usage by various components of my application? or to track the cause of this error?

I recently switched from storing project master data as CSV to using ADO DB. At the same time, I also started using the Variant data type instead of always translating betweem string and single / double.

I followed various memory saving tips that I can find where practical I removed Application.CreateForm (TProject, Project); statements from .dpr And creating them dynamically. (except when forms are used in most cases in any case). In general, I use the smallest practical data type (bytes, shortstream, etc.) and minimize the use of "public" variables and functions.

any advice is very welcome, Brian

+6
source share
5 answers

I doubt that the code you are showing is the source of the problem. This is probably the place where the symptom is observed.

If you suspect that you actually have some basic low level damage, you can try to enable FastMM full debugging mode. For example, problems like the ones you encounter may be caused by general damage to the heap of memory, rather than actual memory exhaustion.

If you do not have cumulative damage, but instead have a memory problem, then searching and solving usually requires a proper tool called a profiler, such as AQTime. Perhaps your allocation code is wrong, as you can understand, if you simply debug your code and find that somewhere you are trying to capture an unreasonable amount of memory, either in one or in a series of calls to some memory allocation function.

However, without a profiler, such as a Nexus or AQTime quality pack or other similar tool, you will be mostly blind. Your application simply fails, and the heap management code reports a shortage of memory. Perhaps you are doing something somewhere that corrupts your heap. Perhaps you are really allocating too much memory for your 32-bit process. Perhaps your computer does not have sufficient real or virtual memory, or that you are allocating a huge data structure that you have not implemented is not practical in your application.

+2
source

EOutOfMemory occurs when the memory manager cannot find a closed memory block for a given allocation request. Thus, you either 1) allocate more memory than you expect, 2) a memory leak that you successfully allocated, or 3) fragmentation (not necessarily a leak) of the memory so that the memory manager continues to allocate more and more memory over time.

When an exception occurs, look at the call stack. This will lead you to code that cannot allocate memory. To get the call stack, run the application in the debugger or use the exception logging infrastructure such as MadExcept, EurekaLog, JCLExcept, etc.

+10
source

Is the full version of FastMem memory manager installed? This can help you identify memory errors. See that you are leaking something.

If you do not have a leak, you have a rather complicated fragmentation problem, you will have to deal with it by maintaining a pool of objects and not preserving their selection / deallocation.

+2
source

To find the cause of OutOfMemory exceptions, you need to look at the creation of all objects, not just where the exception occurs.

The third part tool, such as EurekaLog, can show you all the objects created by the application instance and not correctly located. You can try to fix them using finally finally blocks with the FreeAndNil procedure.

+2
source

Sounds like a memory leak.

I always add

  {$IFDEF DEBUG} ReportMemoryLeaksOnShutdown := DebugHook <> 0; {$ENDIF} 

to the project source file for my debug collections.

This gives a good idea of ​​how well I created the program.

+2
source

Source: https://habr.com/ru/post/912510/


All Articles