- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
FastMM 将此行报告为内存泄漏的来源:
StrClassName := MidStr (curLine, length(START_OF_CLASSNAME)+1, length(curline)+1)
Copy
和 MidStr
怎么了?这只是Delphi 2007编译器的错误,还是更高版本也有这个问题?这是link到 FastMM 报告的副本,以及 image我的应用程序如何显示这些类型的报告。看,为了显示 VirtualTreeView 中的节点,我需要一个新的数据类型。我称之为TMemoryLeak。当我解析报告时,我给我的 TMemoryLeak
一个类名、调用堆栈、它的大小等。但是当应用程序关闭并且 FastMM 启动时,上面的复制行似乎泄漏了内存。我将调用堆栈的大小、整个对象取消分配,但作为字符串的 ClassName 字段始终会占用内存。
更新(来自评论)
这里是声明以及构造函数和解构函数。至于生命周期 - 一旦对象被用来显示节点树,对象的解构函数就会被调用,之后它们就过时了,并被释放(我希望)。
TMemoryLeak = class(TObject)
private
fID :integer;
fSize :integer;
fTotalSize :integer;
fCallStack :TStringList;
fClassName :string;
fRepeatedInstance:integer;
public
property ID :integer read fID write fID;
property TotalSize :Integer read fTotalSize write fTotalSize;
property Size :integer read fSize write fSize;
property CallStack :TStringList read fCallStack write fCallStack;
property ClassName :string read fClassName write fClassName;
property RepeatedInstance :integer read fRepeatedInstance write fRepeatedInstance;
class function Equal(xA: TMemoryLeak; xB: TMemoryLeak): Boolean;
procedure clear;
constructor create;
destructor destroy; override;
end;
TMemoryLeakList=class(TObjectList)
private
fSortType :TMlSortType;
fSortDirection :TMLSortDirection;
fTotalLeakSize :integer;
fClassName :string;
fRepeatedInstance :Integer;
fID :Integer;
function GetItem(Index: Integer): TMemoryLeak;
procedure SetItem(Index: Integer; const Value: TMemoryLeak);
public
property Items[Index: Integer]:TMemoryLeak read GetItem write SetItem; default;
property TotalLeakSize :integer read fTotalLeakSize write fTotalLeakSize;
property SortType :TMLSortType read fSortType write fSortType;
property SortDirection :TMLSortDirection read fSortDirection write fSortDirection;
property ClassName :string read fClassName write fClassName;
property RepeatedInstance :integer read fRepeatedInstance write fRepeatedInstance;
property ID :Integer read fID write fID;
function Add(AObject: TMemoryLeak): Integer;
procedure Clear();
procedure Sort;
constructor create;
destructor destroy; override;
end;
constructor TMemoryLeak.create;
begin
inherited;
fCallStack := TStringList.create;
fRepeatedInstance:=0;
end;
destructor TMemoryLeak.destroy;
begin
clear;
end;
procedure TMemoryLeak.clear;
begin
fCallStack.Clear;
end;
class function TMemoryLeak.Equal(xA, xB: TMemoryLeak): Boolean;
var i:Integer;
begin
Result:=False;
if xA.ClassName = xb.ClassName then
begin
if xA.size = xb.size then
begin
if xA.CallStack.Count = xB.CallStack.Count then
begin
for i := 0 to xa.CallStack.Count - 1 do
begin
if CompareStr(xA.CallStack[i], xB.CallStack[i]) <> 0 then
begin
break;
end;
end;
if i = xa.CallStack.Count then
Result:=True;
end
end
end
end;
{ TMemoryLeakList }
constructor TMemoryLeakList.create;
begin
inherited;
fSortType :=stID;
fSortDirection :=sdAsc;
fClassName :='';
fRepeatedInstance :=0;
end;
destructor TMemoryLeakList.destroy;
begin
Clear;
end;
procedure TMemoryLeakList.Clear;
var i : Integer;
begin
for i := 0 to Count - 1 do
Items[i].clear;
end;
最佳答案
合理的解释是内存泄漏。
我认为您对 FastMM 泄漏报告的工作原理存在误解。您似乎从泄漏报告中推断出 Copy
、MidStr
等是造成泄漏的原因。事实并非如此。当分配内存但随后未释放内存时,会报告泄漏。对于像 Copy
和 MidStr
这样的函数,它们的工作是创建新字符串,这自然涉及内存分配。报告泄漏是因为创建用于保存字符串缓冲区的内存未释放。当其余代码无法释放该内存时,这不是分配函数 Copy
或 MidStr
的错误。
Delphi 2007 是一个成熟的产品,字符串的内存管理是正确的。也许您会进行一些手动内存复制,从而绕过字符串的引用计数。您是否通过调用 FillChar
将某些变量/字段设置为 nil
?您是否使用 FreeMem
而不是 Dispose
来处置记录?前者不会减少字符串引用计数。像这样的事情很可能是泄漏的原因。
查看您发布的代码摘录,这是一个问题:
destructor TMemoryLeakList.destroy;
begin
Clear;
end;
您未能调用继承的析构函数。这意味着列表中的成员不会被销毁。这就解释了为什么你的字符串没有被破坏。
事实上,您不需要为列表类提供析构函数。只需删除它并让继承的 TObjectList 析构函数来完成工作即可。由于 OwnsObjects
默认为 True
,因此列表中的任何成员一旦从列表中删除以及列表本身被销毁,就会立即被销毁。
如果您的 Clear
方法确实清除了列表,那么就会发生这种情况。但您的 Clear
并不是真正的 Clear
。容器中真正的Clear
预计会删除所有成员。您应该删除 Clear
并依赖继承的版本。
在TMemoryLeak
中,您也无法调用继承的析构函数。并且也无法销毁该类拥有的字符串列表实例。
总而言之,我会像这样编写这些构造函数和析构函数:
constructor TMemoryLeak.Create;
begin
inherited;
fCallStack := TStringList.Create;
end;
destructor TMemoryLeak.Destroy;
begin
fCallStack.Free;
inherited;
end;
constructor TMemoryLeakList.Create;
begin
inherited;//by default OwnsObjects is set to True, list manages member lifetime
fSortType :=stID;
fSortDirection :=sdAsc;
end;
然后删除析构函数
,并删除Clear
方法。从 TObjectList
继承的版本就足够了。
在评论中您指出:
The objects' destructors are called as soon as the objects are used to display the node tree. After that they are obsolete, and are deallocated (I hope).
我想说这很可能没有帮助。由于您在 OwnsObjects
模式下创建了对象列表,因此您根本不应该销毁该列表的成员。您已要求列表本身执行此操作。你们不能同时做到。而且“我希望”评论并没有让我对这段代码的正确性充满信心。
由于我们无法看到您的所有代码,因此我无法确定这就是它的全部问题。
最重要的是您的代码存在泄漏。相信FastMM!
关于delphi - 这怎么会是内存泄漏呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13379753/
问题很简单:看代码。两个静态断言都通过了。我不希望第二个通过。这是错误还是正常行为? #include #include template class Temp, class Specializ
int Sequence::scoreDegeneracy() { cout const&) (in /usr/lib/libstdc++.so.6.0.13) ==17043== b
我已经测试了下面的代码,除了第 29 行之外,一切都按照我的预期进行。final.write(invrow) 实际上并没有写入文件。当我使用简单的 print invrow 时,它显示没有问题。我没有
我的项目中有很多类被单例访问,如下所示: _inline GUI_BS_Map* GUI_GetBS_Map() { static GUI_BS_Map obj; return &ob
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
我针对我遇到的问题截取了几张屏幕截图。基本上,我对 vi 的习惯和期望是能够使用箭头键在文档中移动,并且仍然能够阅读文档的实际内容。 Here is a shot of vi editor as I
NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease]; [timeFormatter se
根据docs : The HTMLCanvasElement.toDataURL() method returns a data URI containing a representation of
我做了一个小函数,可以实际测量最大递归限制: def f(x): r = x try: r = f(x+1) except Exception as e:
我正在开发一个小型 silverlight 应用程序,该应用程序涉及在 javascript 和 silverlight 之间传递一些数据。我也在使用 silverlight 虚拟地球控件。 我遇到的
我在Chrome和Firefox中都试过了,浏览器好像没有问题。我的 CSS 是有效的,但是当我通过验证运行我的 HTML 时,它显示“元素链接上属性 rel 的错误值‘stylesheet’:字符串
如果我有一个类,其中的 ctor 设置为像这样的多重注入(inject): public Shogun(IEnumerable allWeapons) { this.allWeapons =
我现在正在使用 devise/omniauth。通过 facebook/twitter 注册后,我想重定向到一个名为“验证电子邮件”的页面,他们可以在其中验证他们的电子邮件地址是否正确。 我只是想让
我有两个相同的交易,在这种情况下发送相同数量的代币,导致实际消耗的气体不同(不是成本,而是显着差异)。 以下是 tx 哈希值: 0x2cbb4b35d87cabe1a7b7bcb562e4e046e9
如果我这样做: ExpiresActive On ExpiresDefault "access plus 30 days" 它没有正确设置 Expire header
我无法过滤我想要查看的特定软件包,因为 cpusettings 菜单呈灰色。 我正在使用 VisualVM 运行程序从 eclipse 运行我的应用程序。 最佳答案 采样过程中无法更改 CPU 设置。
在 http://www.gwtproject.org/doc/latest/DevGuideUiBinder.html 它指出要在 uiBinder 模板中使用小部件: they must be d
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我有下面的代码,但是,当我用 visual studio code 修改代码并在我的 Chrome 浏览器中运行它时,我在“热门产品”中看不到下拉菜单。部分。 但是,当我在此处 (stackoverf
我有两个类(class)联系人和群组 FirstName 和LastName 的组合必须是唯一的,并且可以为单个联系人添加多个地址。我如何在 Entity Framework 代码优先方法中做到这一点
我是一名优秀的程序员,十分优秀!