Delphi: How to find and fix an EOutOfMemory Error?

穿精又带淫゛_ 提交于 2019-12-23 09:26:56

问题


I'm building a delphi application which does scientific simulation. It's growing in complexity & now consists of many units and forms.

I'm starting to get EOutOFMemory Errors each time I run. It seems to happen during or just after I use an Array of variant temporarily within a functions. At risk of asking a really dumb question, is "array of variant" asking for trouble? ( I could convert everything to string, but array of variant in principle saves a lot of fudging things).

the offending array use might 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 task manager - peak memory usage is 42MB, VM is 31M and I'm getting ~90,000 page faults per run. (on an xp machine with 3GB ram)

Does anyone have any general tips on monitoring memory usage by the different components within my application? or on tracing the cause of this error?

Recently I've gone from storing the main project data as CSV to using ADO DBs, At the same time I've also begun using the Variant data type rather than converting betweem string and single/double all the time.

i've followed various memory saving tips I can find like, where practical I've removed the Application.CreateForm(TProject, Project); statements from the .dpr And creating them dynamically. (except where the forms are being used most of the time anyway). Generaly I use smallest practical datatype (byte, shortstring, etc) and minimise use of 'public' variables & functions

any tips very welcome, Brian


回答1:


I doubt that the code you are showing, is the source of the problem. It is probably a place where a symptom occurs.

If you suspect that you have in fact, some basic low level corruption, you might want to try turning on FastMM's Full Debug Mode. For example, problems like the one you're encountering could be caused by general memory heap corruption instead of actually running out of memory.

If you do not have heap corruption, but instead have a true out of memory problem, then finding and solving it usually requires a proper tool, called a profiler, like AQTime. Perhaps your allocation code is wrong in a way you can understand if you simply debug your code, and find that somewhere you are trying to grab an unreasonable amount of memory, either in one, or a series of calls to some memory-allocation function.

However, without a profiler, such as nexus quality suite or AQTime, or another similar tool, you will be mostly blind. Your application is simply failing and the heap management code is reporting it is out of memory. It is possible that you are doing something somewhere that is corrupting your heap. It is possible you are really allocating too much memory for your 32 bit process. It is possible your computer does not have enough real or virtual memory, or that you are allocating a huge data structure that you have not realized is not practical, within your application.




回答2:


EOutOfMemory occurs when the memory manager cannot find a contigious block of memory for a given allocation request. So you are either 1) allocating more memory than you are expecting, 2) leaking memory you have successfully allocated, or 3) fragmenting (not necessarily leaking) memory so the memory manager has to keep allocating more and more memory over time.

When the exception occurs, look at the call stack. That will lead you to the code that is failing to allocate memory. To get the call stack, run your app in the debugger, or use an exception logging framework like MadExcept, EurekaLog, JCLExcept, etc.




回答3:


Have you installed the full version of the FastMem memory manager? It can help you track down errors in memory handling. See if you're leaking something.

If you don't have a leak you have a pretty extreme fragmentation problem, you'll have to deal with it by maintaining a pool of objects rather than keeping allocating/deallocating them.




回答4:


To find a cause of OutOfMemory exceptions you need to look on all objects creation and not just where the exception are raised.

A third part tool like EurekaLog can show you all objects instantiated on application and not correctly disposed. You can try to correct they using try finally blocks with FreeAndNil procedure.




回答5:


Sounds like memory leaks.

I always add a

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

to the project source file for my debug builds.

This gives a good indication of how well I've built the program.



来源:https://stackoverflow.com/questions/10031947/delphi-how-to-find-and-fix-an-eoutofmemory-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!