Virtueller Speicher

Hallo zusammen!
Ich schreibe an einem Java-Programm, daß sehr große Meßdaten verarbeiten muß.
Die Datenmenge ist so groß, daß sie nicht auf einmal in den Arbeitsspeicher passen.
Bietet Java von Haus aus oder mit Hilfe einer Library die Möglichkeit, eine Festplatte als virtuellen Speicher zu verwenden?

(Sprich, im Code muß ich nicht berücksichtigen, ob mein Programm gerade auf echten Speicher oder auf virtuellen Speicher zugreift.
Oder anders formuliert, ich lade die kompletten Meßdaten auf einmal und merke im Code gar nicht, daß ein Teil davon
im virtuellen Speicher liegt.)
 
Die direkte Antwort auf deine Frage kenne ich leider nicht, aber musst du denn wirklich alle Meßdaten auf einmal im Speicher haben?

Evtl. wäre es sinnvoller, über einen Weg nachzudenken, wie man das vermeiden kann und die Daten sequentiell bearbeitet.
 
Natürlich könnte ich die Daten auch sequentiell verarbeiten. Das würde aber alle Verarbeitungs-Algorithmen deutlich verkomplizieren, da ich z.B. die Daten resampeln und filtern, Events finden, oder Kenngrößen berechnen muß.
 
Jedes Betriebssystem bietet die Möglichkeit, Festplattenplatz als Arbeitsspeicher zu gebrauchen. Das nennt sich "Swap"-Bereich bzw. Auslagerungsdatei. Unter Windows ist das die pagefile.sys Datei und unter Linux die swap Partition. Je nachdem, wie groß du diese wählst, können committete/physische Pages des Arbeitsspeichers dorthin ausgelagert werden.
Bezüglich "virtuell": Arbeitsspeicher wird dir vom Betriebssystem immer nur als virtueller Speicher angeboten und sobald eine Page/Seite des virtuell reservierten Arbeitsspeichers angefasst wird (gelesen/geschrieben), wird diese vom Betriebssystem "committet", also erst dann wird dafür tatsächlich physisch freier Speicher gesucht.
 
Das würde aber alle Verarbeitungs-Algorithmen deutlich verkomplizieren,
Würde es das tatsächlich?

Ich nehme jetzt mal was Einfaches an, wie z.B. einen Mittelwert zu bilden.

Du hast also eine List<Double> in der alle Werte sind und rufst im Algorithmus einen Wert nach dem anderen ab, um sie aufzusummieren und am Ende den Mittelwert zu erhalten.

Ob diese Liste jetzt alle Werte im Arbeitsspeicher hat oder es sich um eine FileAccessList<Double> handelt ist doch dem Algo egal. Er funktioniert genauso wie bisher. Allenfalls etwas langsamer. Aber die Schnittstelle des Zugriffs ist identisch!

Ich kann mir gerade nicht vorstellen, welcher Algorithmus gleichzeitig auf sämtliche Werte zugreifen muss (geschweige denn überhaupt kann).

Edit: Es gilt also die FileAccessList<> so zu gestalten, dass der Zugriff möglichst schnell funktioniert, z.B. indem intern immer ein ganzer Block geladen und bereit gestellt wird. Sobald der Block abgearbeitet wurde, wird der nächste geladen oder evtl. in einem separaten Thread bereits eingelesen, solange die Verarbeitung des ersten Blockes noch läuft.

Edit 2: Falls du auf bestimmte Stellen in den Daten zugreifen musst, dann musst du dir eine Struktur überlegen, mit der du indexbasiert arbeiten kannst oder du nimmst gleich eine DatabaseAccessList<> die im Hintergrund eine embedded Datenbank verwendet und importierst dir dorthin deine Messdaten. Dadurch kannst du den Zugriff gestalten, wie du ihn brauchst.
 
Zuletzt bearbeitet:
Ich finde es komplizierter weil:
Schritt 1, Daten filtern und resampeln: Es nutzt nichts, wenn ich die Meßdaten einfach nur abschnittsweise resample und filtere. Ich muß mit dem Ergebnis weiter arbeiten. Also müßte ich die geänderten Meßdaten als neue Meßdatendatei zwischenspeichern.
Generell ist es schwierig, abschnittsweise zu arbeiten, weil man nie einen Abschnitt separat bearbeiten kann.
Stell dir vor, im Abschnitt 2 hast du keinen Wert für die erste Stützstelle des neuen Resample-Rasters. Dann muß du auf den letzten Wert von Abschnitt 1 zurückgreifen. Oder auf mehrere letzte Werte, wenn du einen nicht-linearen Spline zum Interpolieren verwenden möchtest. Theoretisch könnte der vorletzte Wert auch schon im vorletzten Abschnitt liegen. Also mußt du dir doch mehrere Abschnitte merken, obwohl du ja abschnittsweise verarbeiten möchtest.
Schritt 2, Events erkennen: z.B. finde alle Snippets, bei denen von Gang 3 nach Gang 4 geschaltet wurde und die Geschwindigkeit schon seit mindestens 15 Minuten konstant über 50 km/ h liegt. Das kannst du nicht so ohne Weiteres schaffen, wenn du nur die Daten aus dem aktuellen Abschnitt anschaust. Da muß man auch auf die zeitlich früheren Daten zurückgreifen.
Klar, könnte man schon irgendwie programmieren. Aber deswegen sag ich ja, daß alle Algorithmen dann komplizierter werden.
Bisher (ohne sequentielle Verarbeitung) bilde ich logische Vektoren von den einzelnen Meßsignalen und Bedingungen an die Eventerkennung in den Meßdaten und kann diese dann verknüpfen und auch zwischenspeichern, damit man mit einer FileAccessList<Boolean>darauf zugreifen kann
 
Zuletzt bearbeitet:
Ich glaube, wir haben jetzt beide unsere Beiträge noch einmal editiert.
Damit es übersichtlicher wird, fange ich jetzt besser einen neuen Beitrag an.
Ich finde grundsätzlich deinen Ansatz mit einer FileAccessList<> sehr gut.
Vielen Dank für die Idee. So kann ich quasi virtuellen Speicher in Java simulieren,
ohne daß Java (offensichtlich) eine offizielle Möglichkeit dafür anbietet.
Bedenken muß ich nun, wie das ganze möglichst performant wird
und zweitens muß ich viele Zwischenergebnisse zwischenspeichern,
da ich in meinem Workflow mehrere Schritte hintereinander ausführe.
 
Ich glaube, wir haben jetzt beide unsere Beiträge noch einmal editiert.
Damit es übersichtlicher wird, fange ich jetzt besser einen neuen Beitrag an.
Ich finde grundsätzlich deinen Ansatz mit einer FileAccessList<> sehr gut.
Vielen Dank für die Idee. So kann ich quasi virtuellen Speicher in Java simulieren,
ohne daß Java (offensichtlich) eine offizielle Möglichkeit dafür anbietet.
Bedenken muß ich nun, wie das ganze möglichst performant wird
und zweitens muß ich viele Zwischenergebnisse zwischenspeichern,
da ich in meinem Workflow mehrere Schritte hintereinander ausführe.
:):):):)

Wichtig ist, dass du für den Zugriff auf die Daten ein entsprechendes Interface hast, mit dem der Verarbeitungsalgorithmus so auf die Daten zugreifen kann, wie er es für seine Arbeit benötigt.

Wie die Daten in der Datenhaltungsklasse dann gespeichert werden (ganz im Arbeitsspeicher, teilweise im Arbeitsspeicher und teilweise in einer Datei, ganz in einer Datei) kann dem Algorithmus völlig egal sein und macht für ihn keinen Unterschied.

Wenn du Daten (evtl. in der gleichen großen Anzahl) auch zwischenspeichern musst, dann brauchst du ja nur eine neue Datenhaltung zu instantiieren. Evtl. auch mit unterschiedlichen Speichermechanismen. Die Schnittstelle ist das entscheidende!

Data origin = new FileAccessDataStore();
Data puffer = new MemoryAccessDataStore();
Data resampled = new WasWeisDennIchDataStore();

"Data" ist jeweils das Interface und die drei Klassen dahinter sind konkrete Implementationen davon mit wechselndem Speichermechanismus.

Ich persönlich würde die Daten vermutlich in eine Datenbank importieren. Damit ist wahlfreier und schneller Zugriff möglich. Schau dir evtl. mal "H2" an .
 
Zuletzt bearbeitet:
Es nutzt nichts, wenn ich die Meßdaten einfach nur abschnittsweise resample und filtere.
Es muss ja nicht in einzelnen Abschnitten gearbeitet werden, sondern einfach Streambasiert :)

Wenn dann irgendein Filter/Resampler/Whatever Daten aus der Vergangenheit braucht, speichert der sich die nötigen Werte einfach.

ZB für dein Event-Beispiel: der entsprechende Filter hat intern einfach einen Puffer, der das Tempo der letzten 15min enthält. Kommt ein neuer Wert rein, fliegen entsprechend die letzten raus. (Fände ich nicht mal komplizierter als die anderen Dinge)

Für dein anderes Beispiel gibts vermutlich auch Möglichkeiten, dass so zu lösen. Du bist ja nicht plötzlich bei Wert 15825816 und musst genau dann aus allen vorherigen einen passenden dazu raussuchen?
 
ZB für dein Event-Beispiel: der entsprechende Filter hat intern einfach einen Puffer, der das Tempo der letzten 15min enthält. Kommt ein neuer Wert rein, fliegen entsprechend die letzten raus. (Fände ich nicht mal komplizierter als die anderen Dinge)
Und nicht mal das wäre notwendig: Man muss sich nur einen Zeitstempel merken, wann die 50 km/h überschritten wurden und diesen aktualisieren, wenn der gültige Geschwindigkeitsbereich verlassen und wieder betreten wurde. Sobald dann das Schaltereignis kommt, muss man nur noch schauen, ob der Zeitstempel weit genug in der Vergangenheit liegt.
 
Und nicht mal das wäre notwendig: Man muss sich nur einen Zeitstempel merken, wann die 50 km/h überschritten wurden und diesen aktualisieren, wenn der gültige Geschwindigkeitsbereich verlassen und wieder betreten wurde. Sobald dann das Schaltereignis kommt, muss man nur noch schauen, ob der Zeitstempel weit genug in der Vergangenheit liegt.
Stimmt, hatte irgendwie Durchschnitt im Kopf.
 
Was ich gerne noch anfügen würde: Wenn du tatsächlich auf virtuellen Speicher zugreifen mußt (bzw. wenn Windows das für dich tut) bremst das dein Programm drastisch aus, insbesondere wenn der virtuelle Speicher auf einer herkömlichen HDD liegt. Dann wartest du 99% der Zeit auf IO-Operationen.

Von daher würde ich tunlichst alles versuchen, um mit dem vorhandenen Speicher auszukommen.
 
Was ich gerne noch anfügen würde: Wenn du tatsächlich auf virtuellen Speicher zugreifen mußt (bzw. wenn Windows das für dich tut) bremst das dein Programm drastisch aus, insbesondere wenn der virtuelle Speicher auf einer herkömlichen HDD liegt. Dann wartest du 99% der Zeit auf IO-Operationen.

Von daher würde ich tunlichst alles versuchen, um mit dem vorhandenen Speicher auszukommen.
Praktisch wird es sich nicht vermeiden lassen, die Daten in einer Datei zu halten und von dort auszulesen, zumindest wenn es sich um einen herkömmlichen PC handelt und es wirklich sehr viele Daten sind. Datenbanken legen ihre Daten ja auch i.d.R. im Filesystem ab.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben