AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

OutOfMemory Fehler abfangen

Ein Thema von Aviator · begonnen am 29. Jul 2016 · letzter Beitrag vom 2. Aug 2016
Antwort Antwort
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.228 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 10:49
In Verbindung mit einem SQL-Server hat dies dazu geführt, das die Datenmenge immer nur einen Teil geladen hat und erst beim Scrollen z.B. im DBGrid den nächsten Teil nachgeladen hat.
Du weißt aber schon das damit der Server sehr stark belastet wird. Die 2 GB die du nicht mehr auf Clientseite hast muss der Server verwalten.
Und schneller wird die Lösung nicht wenn man meint Mio. Datensätze in einem Grid zu haben.

Wir haben eine Lösung implementiert zuerst nur die Primärschlüsselspalten zu laden und erst bei der Anzeige die weiteren Spalte nachzuladen.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 11:12
Der Anwender tippt ein
SQL-Code:
select *
from hugetable
dein Programm führt aus
SQL-Code:
select * from (
  select *
  from hugetable
) limit 1000 offset 0
Schon gibt es immer nur max. 1000 Zeilen, egal was der Benutzer dort eintippt
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 15:35
Der Anwender tippt ein
SQL-Code:
select *
from hugetable
dein Programm führt aus
SQL-Code:
select * from (
  select *
  from hugetable
) limit 1000 offset 0
Schon gibt es immer nur max. 1000 Zeilen, egal was der Benutzer dort eintippt
Ja die Idee hatte ich auch schon, aber wie setze ich das am Besten um? Ich muss ja dann immer die Daten aus dem zurückgegebenen ResultSet auslesen und an die bereits ausgelesenen Datensätze anhängen wenn der User im Ergebnisbaum scrollt. Es würde zwar sehr lange dauern bis der User ganz unten ankommt, aber theoretisch könnte der Fehler dann ja immer noch auftreten. Die bereits ausgelesenen Datensätze löschen und die Liste immer von vorne füllen ... ich weiß nicht. Ich muss ja auch den Ergebnisbaum so aufbauen, dass der wenigstens so aussieht, als wären 100.000 Datensätze geladen. Dann müsste ich mir ja auch noch merken, wie weit ich bereits war. OK das wäre das Offset das du in deinem Statement beschreibst.

Kannst du das vielleicht noch etwas genauer ausführen?
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#4

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 15:53
in jeder vernünftigen DB-Struktur wird es ja einen PrimaryKey geben, also was spricht dagegen zunächst mal kein
Code:
select * from hugetable
sondern nur ein
Code:
select indexfield from hugetable
zu machen?



Wenn da auch 1mio als ResultSet zurückkommt wird das noch locker in den RAM passen.

Bei der Anzeige(funktioniert super in Grids&VST) wird dann "alles" LineByLine einzeln bei bedarf per separater Query abgefragt und live angezeigt/ausgewertet. Da ist zunächst stets etwas langsamer in Anzeige und Scroll, dafür aber absolut konstant im Verhalten bei quasi beliebig vielen Daten, was der SQL-Server eben hergibt.

Code:
select * from hugetable where indexfield='IndexValue'
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 16:32
in jeder vernünftigen DB-Struktur wird es ja einen PrimaryKey geben, also was spricht dagegen zunächst mal kein
Code:
select * from hugetable
sondern nur ein
Code:
select indexfield from hugetable
zu machen?
Halte ich jetzt nicht für die optimale Idee. In diesem Fall müsste z.B. immer eine Verbindung zur Datenbank bestehen. Wenn diese auf einem Netzlaufwerk liegt, kann es auch schonmal vorkommen, dass das Netzwerk nicht funktioniert. In dem Fall wäre ich bei deiner Lösung in den aktuell angezeigten Zeilen gefangen. Mit meiner Lösung könnte ich weiterhin alle Daten durchsuchen, scrollen und bspw. auch kopieren.

Gibt es denn keine Möglichkeit, ein OutOfMemory Fehler abzufangen und die Instanzen wieder freizugeben die den Speicher belegen?
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.159 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 16:57
Ich kann mir momentan keine Situation vorstellen die es nötig macht 1Mio Datensätze oder mehr im Speicher zu halten?

Lade 100 - wahrscheinlich werden nur 40 auf einmal angezeigt... Wenn der User noch unten Scrollt lade nochmal 100 und vergiss die 1. 50... Fertig..

Abgesehen davon macht das FireDac sowieso - es sei den Du hast FetchAll gesetzt...

Oder mache es wie ein eMail Programm - lade 1000 Header und nur bei Bedarf, die entsprechende Daten die dahinter stecken...

Mavarik
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 17:13
Ich werde es wohl so mal probieren müssen.

Aber es muss doch eine Möglichkeit geben, so einen Fehler generell abfangen zu können.

Ich greife übrigens nicht mit FireDac auf die Datenbank zu sondern benutze zum Zugriff auf die Datenbank direkt die sqlite3.dll. Die Daten werden, wie vorher beschrieben, in einer eigenen Datenstruktur aufbewahrt.
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#8

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 17:29
... In diesem Fall müsste z.B. immer eine Verbindung zur Datenbank bestehen. Wenn diese auf einem Netzlaufwerk liegt, kann es auch schonmal vorkommen, dass das Netzwerk nicht funktioniert. In dem Fall wäre ich bei deiner Lösung in den aktuell angezeigten Zeilen gefangen. Mit meiner Lösung könnte ich weiterhin alle Daten durchsuchen, scrollen und bspw. auch kopieren.

Gibt es denn keine Möglichkeit, ein OutOfMemory Fehler abzufangen und die Instanzen wieder freizugeben die den Speicher belegen?
Ähhh, wenn alles in RAM laden nicht will, bleibt doch nur der live Zugriff auf die Daten(bank), welche schrittweise(mein Beispiel) oder blockweise(siehe SQL Beispiel mit den 1000) je nach Bedarf live nachlädt.

Wenn die Datenquelle extern/unsicher ist, dann muss man sich eben lokal auf Disk (und nicht im RAM) eine Kopie als Zugriffscache erzeugen (also lokale SQliteDB holt sich zunächst per "BatchMove" gemäß UserSQL das was gewünscht ist und speichert das als "ViewResultTable" lokal. Anzeige und Verarbeitung gehen dann Schrittweise/Bockweise mit einer Query auf diese lokale "ViewResultTable".


Datenbanken im Netzwerk per FileZugriff sollte man nicht (mehr) machen. Dafür nehme man einen echtes DBMS was die Clients direkt per Netzwerkprotokoll anbindet.
Wir nehmen im Netzwerk MS-SQLexpress (nur ganz wenig hat bis jetzt den großen MS-SQL Server wirklich gebraucht und genutzt) und als lokales "SQL" meist sogar noch die "access.mdb" Files (SQlite weil portabel für MAC und Mobile aber jetzt für alles neue mit FMX).
Speziell im MobileBereich machen wir immer einen Kompromiss zwischen offlinefähig gecacheten lokalen (Stamm/View)Daten und 100% aktuellen Gesamt(Live)Daten auf den Servern mit online Zwang.
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: OutOfMemory Fehler abfangen

  Alt 30. Jul 2016, 17:40
Ich schreibe ja ein Management Studio für SQLite. In unserer Firma nutzen wir MSSQL. Nur weiß ich ja nicht, wer irgendwann mal auf die Idee kommt und evtl. eine SQLite DB vom Netzwerk aus lädt. Ich würde das auch nicht machen, aber ich bin ja nicht der Endbenutzer. Wenn ich mal fertig bin mit dem Programm, dann dachte ich mir, dass ich es evtl. als Freeware anbiete. Nur bis zu diesem Tag wird es noch ein wenig dauern.

Aber trotzdem nochmal zur eigentlichen Frage zurück: Gibt es keine Möglichkeit, eine OutOfMemory Exception abzufangen und entsprechend nochmal etwas freizugeben? Kann doch nicht sein, dass ein Programm das einmal einen Speicherüberlauf produziert hat nur noch per TaskManager zu beenden ist.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:00 Uhr.
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-2025 by Thomas Breitkreuz