【问题标题】:Unknown memory leak form delphi xe8未知的内存泄漏形式delphi xe8
【发布时间】:2016-03-07 07:35:15
【问题描述】:

我创建了一个简单的应用程序,它在表单 Tform1 上带有一个按钮,用于创建另一个表单 Tform2。 Form2 包含一个工具栏,每个角落有 2 个按钮,标签下方有一个 tabcontrol。我一直在下面得到这个内存泄漏。我确定我正确地创建和销毁了表单。

Screenshot of error

program Project1;

uses
  System.StartUpCopy,
  FMX.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
   ReportMemoryLeaksOnShutdown := True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

这里是创建form2的form1

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
        Hide;
        Application.CreateForm(TForm2, Form2);
        Form2.Show;
        Form2.WindowState := TWindowState.wsMaximized;
end;

end.

带有工具栏和选项卡控件的表单 2

Form2 layout pic

unit Unit2;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.TabControl, FMX.Controls.Presentation;

type
  TForm2 = class(TForm)
    ToolBar1: TToolBar;
    Button1: TButton;
    TabControl1: TTabControl;
    TabItem1: TTabItem;
    TabItem2: TTabItem;
    Label1: TLabel;
    Button2: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := TCloseAction.caFree;
  // ShowMessage('Form Freed now closing whole application') ;
  Application.MainForm.Close;
end;

end.

【问题讨论】:

  • 使用完整的快速 MM 版本来获取与分配相关的堆栈跟踪。但是,您似乎关闭了主窗体两次。
  • @DavidHeffernan 我只是在创建第二个 form2 后隐藏了第一个表单,然后使用 Application.MainForm.Close 从 form2 关闭主窗体,想知道我在哪里关闭了主窗体两次
  • 我不认为这是Delphi版本的问题,我尝试使用XE8并且没有内存泄漏。 “与界面交互”是什么意思? UI 中几乎没有可交互的内容。您是否拥有与此处提供的完全相同的代码?我倾向于使用一个简单的规则进行设计:“无论创造什么,都会破坏”,所以我不会从辅助形式中删除应用程序。不过,这似乎不是你的问题。
  • 如果我们无法重现这一点,我们该如何提供帮助。也许您需要创建一个minimal reproducible example
  • 189-204 bytes: TApplication x 1 表示进程异常终止

标签: delphi memory-leaks firemonkey delphi-xe8


【解决方案1】:

正如我在 cmets 中所说,我无法使用您显示的代码重现内存泄漏报告。但也许你追错了鹅,所以我会冒险猜测一下。

你从来没有解释过你为什么要这样对待Form1,但我有一种奇怪的感觉,它可能是一个登录表单。如果是这样的话,我会这样做:

Project1.dpr

program Project1;

uses
  System.StartUpCopy,
  FMX.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2},
  System.UITypes;  // for the modal result

{$R *.res}

begin
  ReportMemoryLeaksOnShutdown := True;
  Application.Initialize;

  Form1 := TForm1.Create(Application);
  try
  if Form1.ShowModal <> System.UITypes.mrOK then
    Exit;
  finally
    Form1.Free;
  end;

  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

请注意,Form1不是使用Application.CreateForm 创建的。 原因是使用Application.CreateForm 创建的first 表单成为应用程序的主要表单,关闭它会关闭应用程序。相反,我们让主 UI 所在的Form2 成为主窗体,这样我们就可以释放登录后不需要的Form1

现在我们还需要设置登录表单(Form1)的模态结果,例如(但你会想让它更安全):

procedure TForm1.Button1Click(Sender: TObject);
begin
  if (Edit1.Text = 'User') and (Edit2.Text = 'pass') then
    modalresult := System.UITypes.mrOK;
end;

如果这根本不是您要查找的内容,请告诉我,我将删除。

【讨论】:

  • 谢谢 =)。你是对的,我有一个登录表单,它通过 unidac 使用数据库连接。上述方法将登录表单视为模态表单。我不再收到那个错误了。
  • @kami Tedits 中没有闪烁的光标。我测试了您重新分配Application.Mainform 的建议(在一个链接的讨论中),它工作正常。因此,另一种方法是正常创建两个表单(首先使用登录表单),如果登录成功,则更改主表单并释放登录表单。有趣的是,文档说“MainForm 不能在运行时修改(它在运行时是只读的)”。似乎是一个文档错误。
  • @TomBrunberg,谢谢!我只想知道 XE7/8 上的“原始”行为
猜你喜欢
  • 2015-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
相关资源
最近更新 更多