Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

Hallo,

bin grade dabei Stahlplatten mittels 5 Laser zu vermessen (Oberflächenebenheit) und stoß bei der Datenverarbeitung auf gehörige Probleme:

Laser = 2500 Messungen pro Sekunde * 5 = 12500 Werte pro Sekunde

Hab einfach eine List<double[]>, wo ich per Laser immer ein double[] für die Werte habe.

Das ganze soll natürlich visualisiert werden (höhenunterschiede) wobei ich auf 2 Probleme stoße:

1) Bitmap

2) Array

Das Bitmap Problem hab ich schon einigermaßen im Griff (.net erlaubt Bitmaps > 32000 Werte auf der x-Achse nicht).

Das Problem is das Array, mit dem ich die Bitmap befülle. Das Array ist ein Color[,] Array mit (je nach Messdauer) ca. 30000*400 (400 = y achse) Werten.

Dabei bekomm ich beim Erstellen aber immer eine System.OutOfMemoryException, da anscheinend das Array einfach zu groß ist. (12 Mio. Werte).

Kann man da was machen? bzw. iwer Lösungsvorschläge?

Ich denke, dass das Problem nicht bei .NET liegt, sondern letztendlich bei den Datenmengen. Ich würde hier mit einer Reduktion der Datenmenge herangehen, diese ist aber anhand der Problemstellung zu wählen

Das sollte von der Datenmenge eigentlich kein Problem sein.

Dein Color Array für die y Achse belegt ~137MB, das sollte eigentlich zu handlen sein.

I’ve received a number of queries as to why the 64-bit version of the 2.0 .Net runtime still has array maximum sizes limited to 2GB.....

Quelle

Ich hab leider nichts zu den Arraygrenzen für aktuellere Frameworks gefunden.

Aber ich denke da wird irgendwo anders ein Problem sein, jedoch fällt mir dazu jetzt nichts ein.

lg

Gateway

edit:

Wie ließt du denn die Daten ein? Sequentiell?

Ich hab da so meine bedenken das ein .net programm mit solchen Datenmengen in solch kurzer Zeit klar kommt, beziehungsweise kommt das drauf an wie du damit umgehst. Werden die Synchron oder Asynchron eingelesen?

....

Bearbeitet von Gateway_man

Ich hab da so meine bedenken das ein .net programm mit solchen Datenmengen in solch kurzer Zeit klar kommt, beziehungsweise kommt das drauf an wie du damit umgehst. Werden die Synchron oder Asynchron eingelesen?

Ich denke das könnte ein Problem sein bzw. das war in meinem Post gemeint. Die reine Darstellung der Daten, wird nicht das Problem sein, sondern eben die Verarbeitung im Vorfeld. Dafür müsste man aber mehr Infos haben.

Also das mit der 2gb Grenze von Arrays hab ich auch schon gelesen - an dem liegts glaub ich nicht!

Hab zum lesen 5 Threads gemacht, die einfach andauernd daten vom lasercontroller holen (alle 80ms).

Wenn die Messung fertig ist, werden die Threads angehalten und die Verarbeitung beginnt.

Eigentlich ist bis auf das Zeichnen alles ziemlich im grünen Bereich, während dem Lesen liegt die Prozessorlast bei ca. 5 %, Programm reagiert auch super.

Die Verarbeitung mach ich dann mit 2 Pararellisierten For Schleifen (dual core) - kanns vl. an dem liegen? (lock verwend ich zum Setzen der Pixel).

mfg

Ich würde ein Profiling machen, d.h. den Code direkt analysieren. Eine Exception abfangen bringt ja relativ wenig, wenn man die Ursache nicht kennt. Ich denke Debug + Profiling wird hier am sinnvollsten weiterhelfen

Ich kenn ja die Ursache ;)

ich mach

Color[,] color = new Color[bmp.width, bmp.height];

Wobei bmp.width ca. 30000 und bmp.height 400 ist.

Genau bei diesem Aufruf wirft er mir die System.OutOfMemoryException.

Wie groß ist den ein Color Object? Schön langsam befürcht ich doch das es die 2gb sind!

hmm hätte jetzt keine Anzeichen dafür gefunden, dass sie die Grenze weiter gesenkt hätten - meiner Meinung nach wäre das ja auch nicht wirklich sinnvoll in Zeiten von steigendem Arbeitsspeicher :???:

ich denk die war schon immer auf 1,3GB beschränkt in .NET... ist genau so ein müll wie das ne App Domain die länger als 5min keine daten austauscht gelöscht wird und somit runtime exceptions fliegen

ich denk die war schon immer auf 1,3GB beschränkt in .NET..

Siehe Beitrag #3.

Die Grenze war in der 2.0 Version des Frameworks bereits bei 2 GB.

Warum sollten Sie diese dann in den folgeversionen runtersetzen.

Beziehungsweise wäre es schön, wenn du mal irgendeinen Quellverweise liefern würdest, wo man das nachlesen könnte.

lg

Gateway

Was spricht dagegen die Daten auf die Festplatte zu streamen und dann von dort weg stückweise zu verarbeiten ?

Warum verwendest du ein Color-Array und nicht ein Integer Array für die Farbcodierung ?

  • 2 Wochen später...

Meiner Meinung nach liegt das Problem darin begründet, dass der Content deines Array auf dem Stack und nicht auf dem Heap verwaltet wird. In dem Color Objekt befinden sich ja vermutlich int Werte - die Value-Types sind, bei solch einer Menge ist der Stack irgendwann natürlich voll.

Ich würde mal drüber nachdenken ob du wirklich JEDEN erfassten Messpunkt wirklich brauchst, von Punkt 0 zu Punkt 1 sind ja evtl. gar keine großen Sprünge zu erwarten so das die Auflösung ggf. reduziert werden kann.

Wenn jeder Punkt verarbeitet werden muss würde ich die Daten z.B. mit einem MemoryStream sichern. Der Stream liegt auf dem Heap, bei einem 32 Bit OS sollte die Grenze hier bei 2 GB liegen. Wenn die Daten größer werden musst du sie auf die Platte streamen.

Wenn es nur um Visualisierung hatte ich noch nie einen Fall in dem die komplette Struktur auf einmal im RAM gebraucht wurde, mehr Daten zu halten als der Monitor auflösen kann macht keinen Sinn.

Wenn es nur um Visualisierung hatte ich noch nie einen Fall in dem die komplette Struktur auf einmal im RAM gebraucht wurde, mehr Daten zu halten als der Monitor auflösen kann macht keinen Sinn.

Es kommt auf die konkrete Visualisierung an. Wenn Du z.B. einen Graphen, der durch Ähnlichkeiten der Vertices repräsentiert ist, visualisieren willst z.B. mittels Multidimensionale Skalierung ? Wikipedia dann brauchst Du immer die komplette Matrix. Gleiches gilt für eine Hauptkomponentenanalyse ? Wikipedia da hier eine Eigenwertzerlegung für die Korrelationsmatrix gemacht werden muss.

Gerade bei sehr großen Datenmengen passt oft die gesamte Menge nicht mehr in der Speicher. Bei Graphen hätte man z.B. eine quadratisch wachsende Datenmenge, d.h. mit jemanden neuen Vertex steigt die Datenmenge quadratisch. Die genannten Verfahren benötigen leider immer die komplette Menge, so dass man eben sie komplett vorhalten muss

Da die Daten hier ja nach dem einlesen statisch sind sehe ich selbst bei MDS keine Notwendigkeit während der Visualisierung die kompletten Daten halten zu müssen, die nötigen Werte kann man vorberechnen.

Aber ich glaube das war auch gar nicht das ursprüngliche Problem von Murli.

Quelle....

und ich musste das gleiche feststellen....

Hast Du die Quelle (und deren Quelle inkl. der Kommentare) überhaupt gelesen? Dort steht überhaupt nichts von einer "1.3GB" Grenze bei .NET...

Vielmehr kannst Du da nachlesen das Win32 Prozesse auf X86 - System insgesammt (bei einer Windows-Standardkonfiguration) maximal 2 GB pro Prozess verwenden können. Diese 2GB sind der komplette Prozess, d.h. inkl. des Programms, aller DLLs, Runtimes, Threads, Verwaltungsoverhead usw.

@Murli: Ich weiß nicht genau was Du das berchnen möchtest. Aber wenn Du die Daten "häppchenweise" verarbeiten kannt, ist eventuell die MemoryMappedFile-Klasse eine Hilfe für Dich.

Bearbeitet von realgun

Kann man da was machen? bzw. iwer Lösungsvorschläge?

Ohne den gesamten Source zu sehen ist das viel Rumgerate.

Eine 30000x400 Pixel Bitmap ist vom reinen Speicherbedarf her auch nicht zu groß, das sind ja grade mal 12 Megapixel. Andererseits muss man ja auch nicht zwingend Bitmaps mit riesigen Dimensionen aufbauen, um etwas zu visualisieren.

Ich würde zur Visualisierung auch kein Color-Array anlegen, sondern nur die Bitmap und dann in einem unsafe block mit Pointern arbeiten, um die Bitmap mit Daten zu füllen.

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.