09.08.2013, 08:30
Beitrag #1
|
Schü
LVF-Gelegenheitsschreiber
Beiträge: 68
Registriert seit: Sep 2010
2010 Student, 2010, 2012 SP1
2010
DE_EN
08427
Deutschland
|
Datenbanksätze aus Arbeitsspeicher entfernen
Hallo liebe LabView-Forumler,
ich bin aktuell ein kleines Zusatzprogram zu schreiben, mit dem Daten aus einer Datenbank gelesen und "gekürzt" werden. Das heißt der originale Tabelleninhalt wird hergenommen und es werden mehrere Tabellen mit einer Sortierung nach der Zeit für Daten in 1Minuten-, 15Minuten, 1Stunde-, ... bis zu 1Jahr-Abständen hineingeschrieben. Die Datenbankabfrage und das Sortieren, sowie das erstellen einer neuen Tabelle + hineinschreiben ist überhaupt kein Problem.
Mein Problem liegt allerdings wieder einmal in der Arbeitsspeicherverwaltung. Gleich vornweg, nein ich habe kein Problem damit, dass der Arbeitsspeicher volläuft. Hier habe ich dafür gesorgt, dass geöffnete DB-Referenzen auch wieder geschlossen werden etc., soweit mir nichts entgangen ist. Und ich schreibe Arrays auch nur in Schieberegister, ohne dabei unendlich lange Arrays zu haben. Sollte euch dennoch so ein Fehler auffallen, sagt es mir bitte.
Wo ich den eigentlichen Fehler sehe ist, dass ich mittels der Datenbank-VIs von NI eine Tabelle auslese und dabei die Werte in den Arbeitsspeicher geschrieben werden. Wenn das VI dann durchgelaufen ist und beendet wird, bleiben die Daten allerdings im Arbeitsspeicher liegen. Am Ende des VIs benutze ich sogar die Funktion "Speicherfreigabe anfordern".
Liegt es vielleicht daran, dass die Schieberegister und die Verbindungen die Daten noch enthalten bzw. erhalten bleiben, wenn das VI beendet wird?
Ich habe schon verschiedenste Themen dazu gelesen und in vielen wurde ja immer darauf hingewiesen, woran es liegt, dass der Speicher vollläuft. Nur mein Speicher läuft ja nicht voll in dem Sinne, sondern er wird beim Laden von bspw. ca. 205000 Datensätzen mit jeweils 29 Werten - es resultiert also ein 205000x29-Array - einmalig mit ca. 2,8GB vollgepackt. Dadurch steigt die RAM-Auslastung von 2,5GB auf 5,3GB an und bleibt auch dabei, bis das VI beendet wird. Nur nach dem Ende bleiben die Daten wie gesagt im Arbeitsspeicher erhalten, was so nicht gedacht war.
Das ist für mich halt ein grundlegendes Problem, da auch Tabellen mit mehr Datensätzen sortiert werden sollen und je nach Bedarf eine Tabelle in mehreren Durchläufen abgearbeitet werden muss, da nicht alle Datensätze gleichzeitig in den Arbeitsspeicher (bzw. die max. 4GB möglichen) passen können.
Hier habe ich mal einen kurzen Ausschnitt aus meinem Blockdiagramm:
Zudem habe ich noch beide VIs - welche in LV2012 SP1 programmiert wurden:
DB_to_1min.zip (Größe: 46,94 KB / Downloads: 237)
Weitere Lösungsversuche:
(1)
In einem Thema wurde erklärt, dass jedes SubVI eine eigene Kopie anlegt. Dadurch, dass das Select Data-VI von NI ein SubVI ist, dachte ich, dass hier vielleicht der Fehler liegt. Also habe ich den Code heraus kopiert und direkt in mein Blockdiagramm eingefügt. Allerdings hat sich damit nichts geändert. Ist das VI beendet bleiben die Daten im Arbeitsspeicher enthalten.
(2)
Ich habe mal gelesen (glaube hier im Forum), dass man das VI mit einem asynchronen Aufruf öffnen soll und am Ende wieder auf die Standardwerte zurücksetzen soll. Das habe ich versucht, allerdings war das Ergebnis nicht von Erfolg gekrönt. Ich habe es allerdings erstmal dabei belassen - sollte das doch der richtige Weg sein, wäre schön, wenn ihr mir das sagen könnten.
Ich hoffe ich konnte euch alles so genau wie möglich beschreiben.
Beste Grüße vom Schü
|
|
|
09.08.2013, 09:22
Beitrag #3
|
Schü
LVF-Gelegenheitsschreiber
Beiträge: 68
Registriert seit: Sep 2010
2010 Student, 2010, 2012 SP1
2010
DE_EN
08427
Deutschland
|
RE: Datenbanksätze aus Arbeitsspeicher entfernen
Danke schonmal für doe erstem Gedanken,
Zitat:Ist es wirklich notwendig soviele Datensätze aufeinmal von der Datenbank zu lesen? Zur Problemvermeidung im Ansatz würde es doch genügen. Jeweil einen geeigneten kurzen Zeitabschnitt von der DB zu lesen und die reduzierten Daten wieder hineinzuschreiben. Angefangen mit der Reduktion auf Minutenintervall und weitere Durchläufe für die Reduktion auf Stunder, Tage etc.
Ich wollte soviele Daten wie möglich mit einem Durchgang abarbeiten und dachte mir, wenn ich am Endes des VIs den Speicher freigebe ist das ganze nicht so schlimm, dass zwischenzeitlich mal bis zu 4GB Arbeitsspeicher von LabView belegt werden. Aber so eine "Schritt-für-Schritt-Reduktion" muss ich sowieso noch vorsehen, da es ja sein kann, dass eine Datenbank bspw. 1Mio Datensätzen enthält, die nie und nimmer in den Speicher passen. Ich habe auch eine erweiterte/alternative VI-Version, bei der ich nur einen Teil der Datensätze auslese, da nur beim ersten Durchlauf alle bereits bestehenden Daten reduziert werden müssen, wenn ein paar Tage später das VI erneut gestartet wird, sollen ja nicht wieder alle Daten, sondern nur die neu hinzugekommen in die 1-Minute-Tabelle entsprechend hinzugefügt werden.
Den Vorschlag von dir habe ich also schon teilweise umgesetzt bzw. im Hinterkopf gehabt. Allerdings bleibt das Problem bestehen, dass ich die Daten in den Arbeitsspeicher schreibe (egal wieviele) und sie nach dem Ende des VIs noch scheinbar drin stehen.
Zitat:Aber nun noch kurz zu Deinem Problem: Wie verhält sich Dein VI, wen Du zum Abschluß noch einen Durchlauf startest und dabei nur sehr wenige Daten oder besser eine leere Menge von der DB anforderst, dabei aber natürlich nichts in die DB zurückschreibst, in dann die Speicherfreigabe anforderst?
Ich habe das jetzt nocheinmal explizit an zwei Tabellen getestet. Zunächst habe ich die große Tabelle (205000x29) geladen, wodurch der Speicherbedarf von 2,5GB auf 5,45GB anstieg. Danach habe ich das VI mit einer kleineren Tabelle (67500x29) durchlaufen lassen, was auch problemlos funktionierte, ohne dass der Speicherbedarf anwuchs und nach dem Ende lag er weiterhin bei 5,45GB/5,35GB. Wenn ich das VI jetzt allerdings in einem dritten Durchlauf erneut mit der großen Tabelle ausführe, dann steigt der Speicherbedarf solang an, bis halt die Maximalgrenze erreicht wird und LabView gibt den Fehler ""Für diesen Vorgang ist nicht genügend Speicher verfügbar" aus.
Grundsätzliche Vermutung:
Es scheint mir so, als würde LabView für das große Array einen Speicherplatz reservieren und beim folgenden kleinen Array, wird dann der gleiche Speicherbereich genutzt, allerdings nur für einen bestimmten Anteil. Wird jetzt wieder ein großes Array benötigt, so nutzt LabView nicht den bereits reservierten großen Speicherbereich, sondern sieht nur "Aha kleines Array, also muss ich meinen Speicherbereich so und so weit erweitern" - nutzt also immer nur den "letzten Wert" und erweitert diesen dann entsprechend, wodurch der Speicherbedarf von LabView weiter ansteigt.
Das klingt alles etwas verwirrend, aber könnte es so sein?
Wenn dem so ist, dann liese sich mit deinem Vorschlag (max. 1000Zeilen lesen) der Speicherbereich ja konstant halten, oder?
|
|
|
09.08.2013, 09:36
Beitrag #4
|
|
|
09.08.2013, 09:49
Beitrag #5
|
jg
CLA & CLED
Beiträge: 15.864
Registriert seit: Jun 2005
20xx / 8.x
1999
EN
Franken...
Deutschland
|
RE: Datenbanksätze aus Arbeitsspeicher entfernen
Wieso lässt du nicht die Datenbank das Sortieren übernehmen? (Also etwas in der Art : SELECT ... ORDER BY Timestamp DESC )
Damit sparst du dir die doppelte Kopie der Daten, die du aktuell drinnen hast.
Du könntest dir auch gleich einen "Mittelwert" von der Datenbank selber ausgeben lassen.
Bsp: In MySQL funktioniert z.B. SELECT AVG(*) FROM ...
Gruß, Jens
Wer die erhabene Weisheit der Mathematik tadelt, nährt sich von Verwirrung. (Leonardo da Vinci)
!! BITTE !! stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort!
Einführende Links zu LabVIEW, s. GerdWs Signatur.
|
|
|
09.08.2013, 10:03
Beitrag #6
|
|
|
09.08.2013, 10:54
Beitrag #7
|
jg
CLA & CLED
Beiträge: 15.864
Registriert seit: Jun 2005
20xx / 8.x
1999
EN
Franken...
Deutschland
|
RE: Datenbanksätze aus Arbeitsspeicher entfernen
Solange das Ganze interaktiv in der Entwicklungsumgebung läuft, ist natürlich im SubVI immer mind. eine Kopie der Daten (der Datensatz, der im Frontpanel angezeigt wird). Die Speicherfreigabe interessiert LabVIEW da wenig.
Gruß, Jens
Wer die erhabene Weisheit der Mathematik tadelt, nährt sich von Verwirrung. (Leonardo da Vinci)
!! BITTE !! stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort!
Einführende Links zu LabVIEW, s. GerdWs Signatur.
|
|
|
09.08.2013, 11:23
(Dieser Beitrag wurde zuletzt bearbeitet: 09.08.2013 11:31 von Schü.)
Beitrag #8
|
|
|
09.08.2013, 15:00
Beitrag #9
|
Schü
LVF-Gelegenheitsschreiber
Beiträge: 68
Registriert seit: Sep 2010
2010 Student, 2010, 2012 SP1
2010
DE_EN
08427
Deutschland
|
RE: Datenbanksätze aus Arbeitsspeicher entfernen
Hallo nochmal,
da mir die Fähigkeiten fehlen, die Datenreduktion direkt von/in der mysql-Datenbank durchführen zu lassen, bin ich nun den Weg gegangen, dass ich immer nur Blöcke mit 50 Datensätzen aus der Datenbank lese, diese "reduziere" und dann in die neue Datenbank hineinschreibe. Dabei habe ich natürlich immer den letzten Zeitwert übernommmen, damit auch über die gesamte Zeit hinweg die gleichen Zeitabstände eingehalten werden. Genauso ist es möglich, dass später hinzugefügte Daten in die Datenbank eingetragen werden.
Ich habe auch eine Zeitmessung gemacht. Rein aus Interesse. Dabei stellte sich heraus, dass das alte VI (67500x29-Array im Speicher) ca. 2 Minuten langsamer ist, als das neue VI in dem die Datenbank in 50er-Blöcken abgearbeitet wird.
Das fertige VI inklusive SubVIs habe ich im Anhang beigefügt, vielleicht hilft es irgendjemanden mal weiter - sie wurden mit LV2012 SP1 erstellt.
Datenreduktion.zip (Größe: 128,06 KB / Downloads: 231)
Abschließend habe ich noch eine Frage:
Ich habe alle SubVIs mit der Funktion "Speicherfreigabe anfordern" und einer Case-Struktur, welche mit dem Fehlereingang verbunden ist, versehen. Ist es sinnvoll das zu machen oder bringt es keine Vorteile - vielleicht sogar Nachteile?
Sollten euch noch andere Fehler / Verbesserungen auf- oder einfallen, wäre ich froh, wenn ihr sie mir direkt schreibt.
Schon einmal ein schönes Wochenende - Schü
|
|
|
| |