foxjax
asked on
TList of records - memory use
Ok, this one most likely will not have an answer in code but i thought i would ask anyway - got to learn somehow and the books i have don't mention anything of use.
Question: If i have a TList that is used to hold records, is there a way to find out the total memory in bytes used by all of the records in the TList?
Question: If i have a TList that is used to hold records, is there a way to find out the total memory in bytes used by all of the records in the TList?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Evarest: What if i changed the record structure to something like:
TMyRec = record
Item: integer; <== why the change to "byte" above?
Name: array [0..4095] of char;
Period: array [0..1023] of char;
end;
Would that make it easier?
meikl :
I see what you mean by "same string is only once in memory" - i assume delphi just puts a pointer into the place of the string since it already has the string in memory. Sheesh, makes things a lot more complicated on the poor old developer.
TMyRec = record
Item: integer; <== why the change to "byte" above?
Name: array [0..4095] of char;
Period: array [0..1023] of char;
end;
Would that make it easier?
meikl :
I see what you mean by "same string is only once in memory" - i assume delphi just puts a pointer into the place of the string since it already has the string in memory. Sheesh, makes things a lot more complicated on the poor old developer.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>i assume delphi just puts a pointer into the place
yep, but only if the definiton is unlimited (not by string[100])
of course, as if you're using a null-terminated string, Delphi doesn't have need of placing it's contents somewhere else in the memory.
array [0..4095] of char will also place everything on the same place, but doesn't need a #0 terminate.
TMyRec = record
Item: integer; <== why the change to "byte" above?
Name: array [0..4095] of char;
Period: array [0..1023] of char;
end;
I had no reason to change it to byte, but just to give a different example.
[QUOTE]
I see what you mean by "same string is only once in memory" - i assume delphi just puts a pointer into the place of the string since it already has the string in memory. Sheesh, makes things a lot more complicated on the poor old developer.
[/QUOTE]
This sheds light on the fact that you will have to take care that you free your memory correctly! Just calling
var
MyRec: ^TMyRec;
begin
dispose(MyRec);
with MyRec thus a Pointer, will NOT free all memory if the record contains strings.
Finalize(PMyRec(MyRec)^);
thus a record as parameter will free the memory. See my example in your other post for more info...
Evarest
yep, but only if the definiton is unlimited (not by string[100])
of course, as if you're using a null-terminated string, Delphi doesn't have need of placing it's contents somewhere else in the memory.
array [0..4095] of char will also place everything on the same place, but doesn't need a #0 terminate.
TMyRec = record
Item: integer; <== why the change to "byte" above?
Name: array [0..4095] of char;
Period: array [0..1023] of char;
end;
I had no reason to change it to byte, but just to give a different example.
[QUOTE]
I see what you mean by "same string is only once in memory" - i assume delphi just puts a pointer into the place of the string since it already has the string in memory. Sheesh, makes things a lot more complicated on the poor old developer.
[/QUOTE]
This sheds light on the fact that you will have to take care that you free your memory correctly! Just calling
var
MyRec: ^TMyRec;
begin
dispose(MyRec);
with MyRec thus a Pointer, will NOT free all memory if the record contains strings.
Finalize(PMyRec(MyRec)^);
thus a record as parameter will free the memory. See my example in your other post for more info...
Evarest
ASKER
So with defining limits by using array [0..4095] of char, etc i can then get a good approximation of the total memory used by the records?
ASKER
seems sizeof always returns 4 for me - guess i am getting the size of the 4 byte pointer instead of the record in the TList
ASKER
oops - my mistake - got it now.
ASKER
One final point before i close this question:
I assume that to get a realistic approximation of memory used it would be
sizeof(<record>) * <number of records>) + SizeOf(<TList>)* <number of records>
I assume that to get a realistic approximation of memory used it would be
sizeof(<record>) * <number of records>) + SizeOf(<TList>)* <number of records>
"So with defining limits by using array [0..4095] of char, etc i can then get a good approximation of the total memory used by the records?"
Yep
"sizeof(<record>) * <number of records>) + SizeOf(<TList>)* <number of records>"
sizeof(<record>) * <number of records> + SizeOf(<TList>)
is better i guess, i'm not entirely sure though, never done that. It's only logic as you have a TList (thus the definition in the memory) and a lot of record behind eachother (which gives sizeof(<record>) * <number of records>)...
Greetings,
Evarest
Yep
"sizeof(<record>) * <number of records>) + SizeOf(<TList>)* <number of records>"
sizeof(<record>) * <number of records> + SizeOf(<TList>)
is better i guess, i'm not entirely sure though, never done that. It's only logic as you have a TList (thus the definition in the memory) and a lot of record behind eachother (which gives sizeof(<record>) * <number of records>)...
Greetings,
Evarest
ASKER
the reason i did SizeOf(<TList>)* <number of records> is that SizeOf(<TList>) always returns 4 (??) and since i realized that the TList is full of 4 byte pointers to records, i added *<number of records> to allow for the memory used by the 4 bytes per record in the TList.
Make sense?
Make sense?
ASKER
I am going to split the points between the both of you - i raised them to 500 so i can give the original 250 to each of you. I hope you both agree that it is fair.
ASKER
Thanks again guys - i found that quiet informative
in simple
each entry in the list = 4 bytes
plus the size of your record
plus the tlist-size itself
but if you have strings in your record,
then it will be become complicated, because
each same string is only once in memory
associated with a reference counter
meikl ;-)