TObjectList memory leak?
I have this code in Delphi 7:
var
Form1: TForm1;
T: TObjectList;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
And this in Delphi 2009:
var
Form1: TForm1;
T: TObjectList<TPersistent>;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList<TPersistent>.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
According to the Task Manager, when i free T in Delphi 7, all the memory that it used is freed, but in Delphi 2009, the memory is not free and even adds extra 30 kb. Am i missing something? or is there a memory leak in TObjectList in Delphi 2009?
delphi
add a comment |
I have this code in Delphi 7:
var
Form1: TForm1;
T: TObjectList;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
And this in Delphi 2009:
var
Form1: TForm1;
T: TObjectList<TPersistent>;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList<TPersistent>.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
According to the Task Manager, when i free T in Delphi 7, all the memory that it used is freed, but in Delphi 2009, the memory is not free and even adds extra 30 kb. Am i missing something? or is there a memory leak in TObjectList in Delphi 2009?
delphi
1
Ugh, Delphi 2009... not for this issue which obviously is none but for 100 other reasons. Get off that version as soon as you can. Especially if you want to use generics. They are terribly broken so are many other things.
– Stefan Glienke
Nov 22 '18 at 18:02
add a comment |
I have this code in Delphi 7:
var
Form1: TForm1;
T: TObjectList;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
And this in Delphi 2009:
var
Form1: TForm1;
T: TObjectList<TPersistent>;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList<TPersistent>.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
According to the Task Manager, when i free T in Delphi 7, all the memory that it used is freed, but in Delphi 2009, the memory is not free and even adds extra 30 kb. Am i missing something? or is there a memory leak in TObjectList in Delphi 2009?
delphi
I have this code in Delphi 7:
var
Form1: TForm1;
T: TObjectList;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
And this in Delphi 2009:
var
Form1: TForm1;
T: TObjectList<TPersistent>;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
T := TObjectList<TPersistent>.Create(True);
for i := 1 to 10000 do begin
T.Add(TPersistent.Create);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(T);
end;
According to the Task Manager, when i free T in Delphi 7, all the memory that it used is freed, but in Delphi 2009, the memory is not free and even adds extra 30 kb. Am i missing something? or is there a memory leak in TObjectList in Delphi 2009?
delphi
delphi
asked Nov 21 '18 at 22:17
IroncrossIroncross
184
184
1
Ugh, Delphi 2009... not for this issue which obviously is none but for 100 other reasons. Get off that version as soon as you can. Especially if you want to use generics. They are terribly broken so are many other things.
– Stefan Glienke
Nov 22 '18 at 18:02
add a comment |
1
Ugh, Delphi 2009... not for this issue which obviously is none but for 100 other reasons. Get off that version as soon as you can. Especially if you want to use generics. They are terribly broken so are many other things.
– Stefan Glienke
Nov 22 '18 at 18:02
1
1
Ugh, Delphi 2009... not for this issue which obviously is none but for 100 other reasons. Get off that version as soon as you can. Especially if you want to use generics. They are terribly broken so are many other things.
– Stefan Glienke
Nov 22 '18 at 18:02
Ugh, Delphi 2009... not for this issue which obviously is none but for 100 other reasons. Get off that version as soon as you can. Especially if you want to use generics. They are terribly broken so are many other things.
– Stefan Glienke
Nov 22 '18 at 18:02
add a comment |
3 Answers
3
active
oldest
votes
Both versions do not leak. Your confusion stems from using the wrong tool to detect leaks. Memory managers tend to hang on to memory blocks that were recently used, and hope that they can be reused.
If you wish to detect memory leaks use the full FastMM library. That will show you that your code does not leak.
2
AFAIK, in one of the latest versions, FastMM'sReportMemoryLeaksOnShutDown
was moved to System.pas, and can now be used without the explicit use of the FastMM unit.
– Rudy Velthuis
Nov 21 '18 at 23:20
That's true but there is no information beyond the number of blocks leaked. Using FastMM allows you to obtain stack traces at the point of allocoof each leaked block and many other powerful debugging tools.
– David Heffernan
Nov 22 '18 at 7:40
sure, with the explicit fastMM you get much better diagnostics. But I find it useful for a quick check.
– Rudy Velthuis
Nov 22 '18 at 7:47
add a comment |
Task Manager only reports the memory requested by the application through the Windows API. Delphi (just like every other compiler) has its own memory allocator that requests memory from Windows in chunks and then suballocates it as necessary. When you free a Delphi object, or a chunk of memory, it does not necessarily go back to Windows - Delphi's memory allocator simply marks the memory as free so it can be reused in subsequent memory requests. Windows knows nothing about that.
Try to create your own object and override its destructor - you can then put a breakpoint there to check that it indeed gets called.
1
Also note that modern Delphi versions haveReportMemoryLeaksOnShutdown
to detect true memory leaks from Delphi's memory allocator, as only it can know what actually constitutes a leak or not. In Delphi 7, you would have to manually install FastMM to get that same behavior.
– Remy Lebeau
Nov 22 '18 at 2:31
add a comment |
There are no memory leaks. I tested both methods on Delphi XE6 and 10.2.3. I used: "ReportMemoryLeaksOnShutdown := DebugHook <> 0;" and to read memory GetProcessMemoryInfo -> WorkingSetSize.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421218%2ftobjectlistt-memory-leak%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Both versions do not leak. Your confusion stems from using the wrong tool to detect leaks. Memory managers tend to hang on to memory blocks that were recently used, and hope that they can be reused.
If you wish to detect memory leaks use the full FastMM library. That will show you that your code does not leak.
2
AFAIK, in one of the latest versions, FastMM'sReportMemoryLeaksOnShutDown
was moved to System.pas, and can now be used without the explicit use of the FastMM unit.
– Rudy Velthuis
Nov 21 '18 at 23:20
That's true but there is no information beyond the number of blocks leaked. Using FastMM allows you to obtain stack traces at the point of allocoof each leaked block and many other powerful debugging tools.
– David Heffernan
Nov 22 '18 at 7:40
sure, with the explicit fastMM you get much better diagnostics. But I find it useful for a quick check.
– Rudy Velthuis
Nov 22 '18 at 7:47
add a comment |
Both versions do not leak. Your confusion stems from using the wrong tool to detect leaks. Memory managers tend to hang on to memory blocks that were recently used, and hope that they can be reused.
If you wish to detect memory leaks use the full FastMM library. That will show you that your code does not leak.
2
AFAIK, in one of the latest versions, FastMM'sReportMemoryLeaksOnShutDown
was moved to System.pas, and can now be used without the explicit use of the FastMM unit.
– Rudy Velthuis
Nov 21 '18 at 23:20
That's true but there is no information beyond the number of blocks leaked. Using FastMM allows you to obtain stack traces at the point of allocoof each leaked block and many other powerful debugging tools.
– David Heffernan
Nov 22 '18 at 7:40
sure, with the explicit fastMM you get much better diagnostics. But I find it useful for a quick check.
– Rudy Velthuis
Nov 22 '18 at 7:47
add a comment |
Both versions do not leak. Your confusion stems from using the wrong tool to detect leaks. Memory managers tend to hang on to memory blocks that were recently used, and hope that they can be reused.
If you wish to detect memory leaks use the full FastMM library. That will show you that your code does not leak.
Both versions do not leak. Your confusion stems from using the wrong tool to detect leaks. Memory managers tend to hang on to memory blocks that were recently used, and hope that they can be reused.
If you wish to detect memory leaks use the full FastMM library. That will show you that your code does not leak.
answered Nov 21 '18 at 22:49
David HeffernanDavid Heffernan
515k348151207
515k348151207
2
AFAIK, in one of the latest versions, FastMM'sReportMemoryLeaksOnShutDown
was moved to System.pas, and can now be used without the explicit use of the FastMM unit.
– Rudy Velthuis
Nov 21 '18 at 23:20
That's true but there is no information beyond the number of blocks leaked. Using FastMM allows you to obtain stack traces at the point of allocoof each leaked block and many other powerful debugging tools.
– David Heffernan
Nov 22 '18 at 7:40
sure, with the explicit fastMM you get much better diagnostics. But I find it useful for a quick check.
– Rudy Velthuis
Nov 22 '18 at 7:47
add a comment |
2
AFAIK, in one of the latest versions, FastMM'sReportMemoryLeaksOnShutDown
was moved to System.pas, and can now be used without the explicit use of the FastMM unit.
– Rudy Velthuis
Nov 21 '18 at 23:20
That's true but there is no information beyond the number of blocks leaked. Using FastMM allows you to obtain stack traces at the point of allocoof each leaked block and many other powerful debugging tools.
– David Heffernan
Nov 22 '18 at 7:40
sure, with the explicit fastMM you get much better diagnostics. But I find it useful for a quick check.
– Rudy Velthuis
Nov 22 '18 at 7:47
2
2
AFAIK, in one of the latest versions, FastMM's
ReportMemoryLeaksOnShutDown
was moved to System.pas, and can now be used without the explicit use of the FastMM unit.– Rudy Velthuis
Nov 21 '18 at 23:20
AFAIK, in one of the latest versions, FastMM's
ReportMemoryLeaksOnShutDown
was moved to System.pas, and can now be used without the explicit use of the FastMM unit.– Rudy Velthuis
Nov 21 '18 at 23:20
That's true but there is no information beyond the number of blocks leaked. Using FastMM allows you to obtain stack traces at the point of allocoof each leaked block and many other powerful debugging tools.
– David Heffernan
Nov 22 '18 at 7:40
That's true but there is no information beyond the number of blocks leaked. Using FastMM allows you to obtain stack traces at the point of allocoof each leaked block and many other powerful debugging tools.
– David Heffernan
Nov 22 '18 at 7:40
sure, with the explicit fastMM you get much better diagnostics. But I find it useful for a quick check.
– Rudy Velthuis
Nov 22 '18 at 7:47
sure, with the explicit fastMM you get much better diagnostics. But I find it useful for a quick check.
– Rudy Velthuis
Nov 22 '18 at 7:47
add a comment |
Task Manager only reports the memory requested by the application through the Windows API. Delphi (just like every other compiler) has its own memory allocator that requests memory from Windows in chunks and then suballocates it as necessary. When you free a Delphi object, or a chunk of memory, it does not necessarily go back to Windows - Delphi's memory allocator simply marks the memory as free so it can be reused in subsequent memory requests. Windows knows nothing about that.
Try to create your own object and override its destructor - you can then put a breakpoint there to check that it indeed gets called.
1
Also note that modern Delphi versions haveReportMemoryLeaksOnShutdown
to detect true memory leaks from Delphi's memory allocator, as only it can know what actually constitutes a leak or not. In Delphi 7, you would have to manually install FastMM to get that same behavior.
– Remy Lebeau
Nov 22 '18 at 2:31
add a comment |
Task Manager only reports the memory requested by the application through the Windows API. Delphi (just like every other compiler) has its own memory allocator that requests memory from Windows in chunks and then suballocates it as necessary. When you free a Delphi object, or a chunk of memory, it does not necessarily go back to Windows - Delphi's memory allocator simply marks the memory as free so it can be reused in subsequent memory requests. Windows knows nothing about that.
Try to create your own object and override its destructor - you can then put a breakpoint there to check that it indeed gets called.
1
Also note that modern Delphi versions haveReportMemoryLeaksOnShutdown
to detect true memory leaks from Delphi's memory allocator, as only it can know what actually constitutes a leak or not. In Delphi 7, you would have to manually install FastMM to get that same behavior.
– Remy Lebeau
Nov 22 '18 at 2:31
add a comment |
Task Manager only reports the memory requested by the application through the Windows API. Delphi (just like every other compiler) has its own memory allocator that requests memory from Windows in chunks and then suballocates it as necessary. When you free a Delphi object, or a chunk of memory, it does not necessarily go back to Windows - Delphi's memory allocator simply marks the memory as free so it can be reused in subsequent memory requests. Windows knows nothing about that.
Try to create your own object and override its destructor - you can then put a breakpoint there to check that it indeed gets called.
Task Manager only reports the memory requested by the application through the Windows API. Delphi (just like every other compiler) has its own memory allocator that requests memory from Windows in chunks and then suballocates it as necessary. When you free a Delphi object, or a chunk of memory, it does not necessarily go back to Windows - Delphi's memory allocator simply marks the memory as free so it can be reused in subsequent memory requests. Windows knows nothing about that.
Try to create your own object and override its destructor - you can then put a breakpoint there to check that it indeed gets called.
edited Nov 22 '18 at 2:28
Remy Lebeau
332k18251443
332k18251443
answered Nov 21 '18 at 22:32
Dmitry StreblechenkoDmitry Streblechenko
42.4k32760
42.4k32760
1
Also note that modern Delphi versions haveReportMemoryLeaksOnShutdown
to detect true memory leaks from Delphi's memory allocator, as only it can know what actually constitutes a leak or not. In Delphi 7, you would have to manually install FastMM to get that same behavior.
– Remy Lebeau
Nov 22 '18 at 2:31
add a comment |
1
Also note that modern Delphi versions haveReportMemoryLeaksOnShutdown
to detect true memory leaks from Delphi's memory allocator, as only it can know what actually constitutes a leak or not. In Delphi 7, you would have to manually install FastMM to get that same behavior.
– Remy Lebeau
Nov 22 '18 at 2:31
1
1
Also note that modern Delphi versions have
ReportMemoryLeaksOnShutdown
to detect true memory leaks from Delphi's memory allocator, as only it can know what actually constitutes a leak or not. In Delphi 7, you would have to manually install FastMM to get that same behavior.– Remy Lebeau
Nov 22 '18 at 2:31
Also note that modern Delphi versions have
ReportMemoryLeaksOnShutdown
to detect true memory leaks from Delphi's memory allocator, as only it can know what actually constitutes a leak or not. In Delphi 7, you would have to manually install FastMM to get that same behavior.– Remy Lebeau
Nov 22 '18 at 2:31
add a comment |
There are no memory leaks. I tested both methods on Delphi XE6 and 10.2.3. I used: "ReportMemoryLeaksOnShutdown := DebugHook <> 0;" and to read memory GetProcessMemoryInfo -> WorkingSetSize.
add a comment |
There are no memory leaks. I tested both methods on Delphi XE6 and 10.2.3. I used: "ReportMemoryLeaksOnShutdown := DebugHook <> 0;" and to read memory GetProcessMemoryInfo -> WorkingSetSize.
add a comment |
There are no memory leaks. I tested both methods on Delphi XE6 and 10.2.3. I used: "ReportMemoryLeaksOnShutdown := DebugHook <> 0;" and to read memory GetProcessMemoryInfo -> WorkingSetSize.
There are no memory leaks. I tested both methods on Delphi XE6 and 10.2.3. I used: "ReportMemoryLeaksOnShutdown := DebugHook <> 0;" and to read memory GetProcessMemoryInfo -> WorkingSetSize.
edited Nov 22 '18 at 0:04
answered Nov 21 '18 at 23:58
janeks3janeks3
354
354
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421218%2ftobjectlistt-memory-leak%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Ugh, Delphi 2009... not for this issue which obviously is none but for 100 other reasons. Get off that version as soon as you can. Especially if you want to use generics. They are terribly broken so are many other things.
– Stefan Glienke
Nov 22 '18 at 18:02