本文介绍了Delphi:如何查找和修复EOutOfMemory错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个进行科学模拟的delphi应用程序。
它的复杂性与日俱增现在由许多单元和表格组成。

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

每次运行时,我都会收到EOutOFMemory错误。这似乎是在函数中临时使用变体数组期间或之后发生的。冒着提出一个非常愚蠢的问题的风险,变量数组是否会带来麻烦? (我可以将所有内容都转换为字符串,但原则上可以使用变体数组来节省很多麻烦的事情。)

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).

有问题的数组可能是:

 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);

在任务管理器中-峰值内存使用量为42MB,VM为3100万,我得到的页面约为90,000每次运行的故障。 (在具有3GB内存的xp计算机上)

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?

最近我已经从将主要项目数据存储为CSV到使用ADO DB,
我还开始使用Variant数据类型,而不是一直转换betweem字符串和单/双。

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.

我遵循了各种内存节省技巧,在实际操作中,我删除了Application.CreateForm(TProject,Project); .dpr中的语句并动态创建它们。 (除非无论如何大多数时候都在使用表格)。通常,我会使用最小的实际数据类型(字节,短字符串等),并尽量减少使用公共变量&函数

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

推荐答案

我怀疑您显示的代码是问题的根源。它可能是出现症状的地方。

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

如果您怀疑自己确实存在一些基本的底层损坏,则可以尝试打开FastMM的完全调试模式。例如,您遇到的问题可能是由于一般的内存堆损坏而不是实际上内存不足而引起的。

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.

如果您没有堆损坏,而是遇到了真正的内存不足问题,那么找到并解决它通常需要一个称为Profiler的适当工具,例如AQTime 。也许您的分配代码是错误的,您可以通过简单地调试代码的方式来理解它,并发现某个地方正在尝试获取不合理的内存,无论是一次调用还是对一系列内存分配函数的调用。

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.

但是,如果没有分析器(例如nexus质量套件或AQTime)或其他类似工具,则您几乎是盲目的。您的应用程序完全失败,堆管理代码报告它的内存不足。您可能正在某个地方破坏了堆。您可能确实为32位进程分配了过多的内存。
可能是您的计算机没有足够的实际或虚拟内存,或者您正在分配一个尚未意识到的不实际的巨大数据结构。

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.

这篇关于Delphi:如何查找和修复EOutOfMemory错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 01:18