Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   hat TStringgrig eine innere Größenbeschränkung? (https://www.delphipraxis.net/154564-hat-tstringgrig-eine-innere-groessenbeschraenkung.html)

p80286 15. Sep 2010 18:21

hat TStringgrig eine innere Größenbeschränkung?
 
Guten Tag zusammen,

bei der Ausgabe einer Datenbankabfrage erhalte ich folgenden Fehler:

Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt SQL_CLIENT.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 0047FBE9 in Modul 'SQL_CLIENT.exe'. Lesen von Adresse 0003FFFC' aufgetreten.

Dann sind ca 150.000 der 240.000 Datensätze verarbeitet.
lenke ich die Ausgabe in ein TMemo um ist der Speicherverbrauch nicht ganz so hoch (ist ja eigentlich klar) und alles klappt.

hier der zugehörige Source-Code:
Delphi-Quellcode:
procedure INSTRINGGRID(ins:string;sg:tstringgrid);
var
  i     : integer;
  fldcnt : integer;
begin
  fldcnt:=1;
  for i:=1 to length(ins) do
    if ins[i]=#9 then inc(fldcnt,1);
  if sg.ColCount<fldcnt then sg.colcount:=fldcnt;
  for i:=1 to fldcnt do
    sg.cells[i-1,sg.rowcount-1]:=feld(ins,i);
  sg.rowcount:=sg.rowcount+1;
end;


 for i:=0 to tl.count-1 do begin
        try
          INSTRINGGRID(tl[i],form1.StringGrid1);
        except
          showmessage('Fehler bei Datenausgabe in Stringgrid aufgetreten Datensatz Nr'+inttostr(i));
          break;
        end;
        form1.L_Grid_Count.caption:=inttostr(i)+' von '+inttostr(tl.count);
      end;
Ich vermute, daß schlicht und ergreifend der Speicher am Ende ist, und das darum die obige Fehlermeldung Blödsinn ist. Oder liege ich da falsch?

mkinzler 15. Sep 2010 18:25

AW: hat TStringgrig eine innere Größenbeschränkung?
 
Wie sinnvoll ist es 240.000 Datensätze in einem Grid anzuzeigen?

idefix2 15. Sep 2010 18:28

AW: hat TStringgrig eine innere Größenbeschränkung?
 
Ich würde mich Deiner Vermutung und der Frage MKinzlers anschliessen

shmia 15. Sep 2010 18:43

AW: hat TStringgrig eine innere Größenbeschränkung?
 
Diese Zeile
Delphi-Quellcode:
sg.rowcount:=sg.rowcount+1;
ist natürlich besonders schmerzhaft.
Durch das Anhängen von einzelnen Zeilen werden intern jede Menge Speicherreservierung vorgenommen und zig Windows-Messages verschickt.
Wenn man das Grid von Anfang an die richtige Grösse gibt, dann wird es viel effizienter.

alzaimar 15. Sep 2010 18:56

AW: hat TStringgrig eine innere Größenbeschränkung?
 
Zitat:

Zitat von mkinzler (Beitrag 1049884)
Wie sinnvoll ist es 240.000 Datensätze in einem Grid anzuzeigen?

Extrem-Scrolling als Antiaggressionstherapie?
:stupid:

p80286 16. Sep 2010 11:43

AW: hat TStringgrig eine innere Größenbeschränkung?
 
erst einmal vielen Dank!

die 240.000 Datensätze sind dann sinnvoll, wenn mann versucht heraus zu bekommen, was eigentlich in der Tabelle steht.
(das Extrem-Scrolling ist gut! muß ich mal versuchen)
Zitat:

Zitat von shmia (Beitrag 1049891)
Diese Zeile
Delphi-Quellcode:
sg.rowcount:=sg.rowcount+1;
ist natürlich besonders schmerzhaft.
Durch das Anhängen von einzelnen Zeilen werden intern jede Menge Speicherreservierung vorgenommen und zig Windows-Messages verschickt.
Wenn man das Grid von Anfang an die richtige Grösse gibt, dann wird es viel effizienter.

kann ich Rowcount auch erst zum bitteren Ende setzen?
Die OH war da nicht so eindeutig, und die Praxis schein nicht dagegen zu sprechen.

Gruß
K-H

Bernhard Geyer 16. Sep 2010 11:54

AW: hat TStringgrig eine innere Größenbeschränkung?
 
Schau den benötigten Speicher an?
Integriert FastMM um die Speicherfragmentierung des alten Memory-Managers zu umgehen.

p80286 16. Sep 2010 17:22

AW: hat TStringgrig eine innere Größenbeschränkung?
 
fastMM war eine gute Empfehlung. Da ist prompt eine Schusseligkeit in einer alten Unit hochgekommen, aber der Fehler bleibt.
Ich hab es mal mit
Delphi-Quellcode:
for i:=0 to maxint do
  stringgrid1.cells[0,i]:=inttohex(i,8);
versucht.
Das läuft, wie zu erwarten, vor die Speicherwand. Es sieht so aus, als würde der Fehler durch eine bestimmte Kombination aus Daten/Satznummer verursacht.
Mal weiter testen, vielleicht finde ich noch etwas.

Edith:
Jetzt ist der Cursor zum ersten Mal im Sourcecode zu sehen gewesen. Könnt Ihr mit dieser Routine etwas anfangen?
Delphi-Quellcode:
unit Grids


function TSparsePointerArray.MakeAt(Index: Integer): PPointer;
var
  dirP: PSecDir;
  p: Pointer;
  byteP: PChar;
  secIndex: Word;
begin
  { Expand Section Directory if necessary. }
  secIndex := Index shr secShift;      { Unsigned shift }
  if secIndex >= slotsInDir then
    dirP := expandDir(secDir, slotsInDir, secIndex + 1)
  else
    dirP := secDir;

  { Index into Section Directory using high order part of
    index. Get pointer to Section. If null, create new
    Section. Index into Section using low order part of index. }
  secDir := dirP;
  p := dirP^[secIndex];{------------------------------ hier stet der Cursor !!!!!
  if p = nil then begin
    p := makeSec(secIndex, FSectionSize);
    dirP^[secIndex] := p
  end;
  byteP := p;
  Inc(byteP, (Index and indexMask) * SizeOf(Pointer));
  if Index > FHighBound then
    FHighBound := Index;
  Result := PPointer(byteP);
  cachedIndex := -1
end;
Gruß
K-H

shmia 16. Sep 2010 18:02

AW: hat TStringgrig eine innere Größenbeschränkung?
 
Zitat:

Zitat von p80286 (Beitrag 1050130)
Delphi-Quellcode:
for i:=0 to maxint do
  stringgrid1.cells[0,i]:=inttohex(i,8);
Das läuft, wie zu erwarten, vor die Speicherwand

maxint ist gleich 2147483647 :shock:
Das ist eine völlig andere Größenordnung als ~300000.

Zitat:

Zitat von p80286
kann ich Rowcount auch erst zum bitteren Ende setzen?
Die OH war da nicht so eindeutig, und die Praxis schein nicht dagegen zu sprechen.

Nein, RowCount muss gesetzt werden bevor die Zellen mit Daten befüllt werden.

Also ein Stringgrid mit 300000 Zeilen ist eigentlich "gar kein Problem":
Delphi-Quellcode:
var
   i : Integer;
begin
   StringGrid1.RowCount := 300000; // VORHER setzen !
   for i := 1 to StringGrid1.RowCount-1 do
      StringGrid1.Cells[1, i] := IntToStr(i);
end;
Die Schleife braucht zwar ~4 Minuten bis sie fertig ist,
aber Anzeigen und Scrollen funktioniert.
Interessanterweise dauert das Beenden des Programms ca 1,5 Minuten;
im Hintergrund werden wohl einige Hunderttausende Windows-Botschaften verschickt
und das braucht Zeit.

p80286 16. Sep 2010 18:45

AW: hat TStringgrig eine innere Größenbeschränkung?
 
Zitat:

Zitat von shmia (Beitrag 1050138)
Also ein Stringgrid mit 300000 Zeilen ist eigentlich "gar kein Problem":

Keine Einwände.

Zitat:

Zitat von shmia (Beitrag 1050138)
Interessanterweise dauert das Beenden des Programms ca 1,5 Minuten;
im Hintergrund werden wohl einige Hunderttausende Windows-Botschaften verschickt
und das braucht Zeit.

Ich würde das auf's "Speicheraufräumen" schieben, so ca. ein Gig muß ja schließlich ordentlich entsorgt werden.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:04 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz