Bonjour,
Comment connaître la taille de la mémoire d'un objet TStrings ?
Exemple quelle est la mémoire occupée par TMemo.lines ? ou TListBox.Items ? Après que ces objets ont été initialisés par un code source ?
Merci à tous
Version imprimable
Bonjour,
Comment connaître la taille de la mémoire d'un objet TStrings ?
Exemple quelle est la mémoire occupée par TMemo.lines ? ou TListBox.Items ? Après que ces objets ont été initialisés par un code source ?
Merci à tous
Dans quel but souhaites-tu connaitre la taille en mémoire d'un TStrings ?
Est-ce que le problème ne serait pas plutot comment faire avec une liste vraiment longue et éviter de tout charger en mémoire ? Voire, j'ai déjà une liste d'objet avec les infos dedans, comment puis-je afficher une propriété particulière de ces objets sans pour autant copier toutes les valeurs ?
J'initialise un objet TStrings et je dois le passer dans un buffer. Il me faut donc connaître la taille du Strings pour dimensionner le buffer
Bonjour,
Pour passer un Tstrings dans un buffer et le récupérer, on peut utiliser la propriété Tstrings.Text.
Tu veux passer une instance de TStrings dans un buffer ?
Mais tu n'auras qu'un Integer dans ton buffer, TStrings c'est un objet, pas un record, donc tu ne peux pas avoir la main sur l'objet en entier mais juste sur l'endroit où il se trouve.
Tu peux en revanche passer les données qui t'intéressent en extrayant le contenu grâce à la property Text de TStrings (comme l'indique Graffito).
Et la fonction sizeof elle te permet pas de recupérer la taille du TStrings?
Non. Dans Delphi, une variable objet n'est qu'une référence, un pointeur. Sa taille est toujours de 4 octets.
colorid, ta question est mal formulée.
Pour commencer, comme déjà indiqué, la taille que tu cherches sera donnée par :
ouCode:Length(TListBox.Items.Text)
Mais, la mémoire occupée par un TStrings est supérieure à la taille occupée par les chaînes mises bout à bout : il y a l'espace occupé par la référence, puis par l'objet lui-même, puis par les pointeurs et les compteurs de référence des chaînes, etc. Bref, l'espace mémoire occupé par un TStringList est supérieur à length(Text).Code:Length(TMemo.Lines.Text)
Tient, ce genre de code peut t'inspirer pour la prévision d'allocation, bon l'exemple est une TList mais cela revient quasiment au même
Pour Compléter/Paraphrasé CapJack
TStringList (Pointer) = 4;
TStringList (InstanceSize) = 48; // c'est juste les pointeurs, ensuite tu des tableaux cachés ...
FList (Pointer) 4, normalement contenu dans les 48
FList (Array) = Capactiy * (SizeOf(PStringItem) + SizeOf(TStringItem));
TStringItem = 8, mais faut ajouté comme le dit CapJack, SizeOf(StrRec^) (voir System.pas) + 2 car cela alloue les deux zéros terminals d'une WideString pour faciliter la conversion PChar
...
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 var _RecList: TList; MSbn, MSan, MSad: TMemoryStatus; HSbn, HSan, HSad: THeapStatus; type PRecItem = ^TRecItem; TRecItem = record S: string; I: Integer; end; procedure TFrmTestStructureMemoire.BtnNewMassClick(Sender: TObject); var irl: Integer; pir: PRecItem; Cumul: Integer; begin if Assigned(_RecList) then BtnDisposeMass.Click(); GlobalMemoryStatus(MSbn); HSbn := GetHeapStatus(); lblBeforeNewMass.Caption := Format('%d o, %d o', [MSbn.dwTotalPhys - MSbn.dwAvailPhys, HSbn.TotalAllocated]); _RecList := TList.Create(); Cumul := 0; for irl := 1 to 5000 do begin New(pir); pir^.S := Format('Item n°%d : %s', [irl, FormatDateTime('Le dddd d mmmm yyyy à hh:nn:ss zzz', Now())]); pir^.I := irl; Inc(Cumul, Length(pir^.S) + 8 + 2); // +8 car Len+OccCount, +2 car Cela alloue pour les #0 terminal Wide _RecList.Add(pir); end; Cumul := (_RecList.Capacity * SizeOf(Pointer)) + (_RecList.Count * SizeOf(TRecItem)) + Cumul; GlobalMemoryStatus(MSan); HSan := GetHeapStatus(); lblAfterNewMass.Caption := Format('%d o, %d o', [MSan.dwTotalPhys - MSan.dwAvailPhys, HSan.TotalAllocated]); lblNewPrevision.Caption := Format('%d o, %d o', [Cumul, HSbn.TotalAllocated + Cumul]); lblNewReal.Caption := Format('%d o', [(MSan.dwTotalPhys - MSan.dwAvailPhys) - (MSbn.dwTotalPhys - MSbn.dwAvailPhys)]); end; procedure TFrmTestStructureMemoire.BtnDisposeMassClick(Sender: TObject); var irl: Integer; begin if Assigned(_RecList) then begin for irl := 0 to _RecList.Count - 1 do Dispose(PRecItem(_RecList.Items[irl])); _RecList.Free(); _RecList := nil; end; GlobalMemoryStatus(MSad); HSad := GetHeapStatus(); lblAfterDisposeMass.Caption := Format('%d o, %d o', [MSad.dwTotalPhys - MSad.dwAvailPhys, HSad.TotalAllocated]); lblFinal.Caption := Format('%d o', [(MSad.dwTotalPhys - MSad.dwAvailPhys) - (MSbn.dwTotalPhys - MSbn.dwAvailPhys)]); end;