Guten Tag,
ich setze hier einen MSP430 ein und arbeite mit string-Objekten. Bevor
das "warum" kommt:
1.) Gibt der Controller/die Anwendung das her
2.) Muss ich wirklich viel mit Dateien und Verzeichnissen arbeiten, da
ist die string-Klasse eine Erleichterung.
Jetzt das Problem:
------------------
Heap hatte ich auf 512 Bytes eingestellt.
Der Ablauf ist folgender: Ich baue mir aus der aktuellen Uhrzeit/dem
aktuellen Datum jeweils den aktuellen Pfad zu den Dateien&Verzeichnissen
zusammen und verwende dafür ein string-Objekt 'pathToFile'. Nach einer
Weile hängt sich mein Programm auf. Und zwar genau wenn die nachfolgende
erste Zeile mit dem "if" ins Spiel kommt:
1
if(pathToFile!=file.getPathToFile()){
2
/* Hier ist alles auskommentiert, theoretisch würde jetzt aber die alte Datei geschlossen und eine neue geöffnet werden. */
3
}
4
5
// Das macht 'getPathToFile'
6
conststring&getPathToFile()const{
7
returnm_pathToFile;
8
}
Kommentiere ich diese if-Bedingung aus, dann läuft das Programm, ist der
Abgleich drinne knallt es nach ein paar Sekunden.
Erhöhe ich jetzt den Heap von 512 auf 768 Bytes, dann scheint die
Anwendung korrekt zu laufen. Hier verstehe ich den Hintergrund nicht.
Meine Vermutung war das der Destruktor des strings zwar Heap-Speicher
freigibt, dieser aber fragmentiert wird und es deswegen igendwann
knallt.
Dagegen spricht, dass es mit 768 Bytes endlos läuft. Dagegen spricht
auch, das das Programm nicht abstürzt, wenn die if-Bedingung nicht
ausgeführt wird, obwohl hier laufend string-Objekte angelegt und
zerstört werden.
Was kann das sein?
Verbatim schrieb:> Meine Vermutung war das der Destruktor des strings zwar Heap-Speicher> freigibt, dieser aber fragmentiert wird und es deswegen igendwann> knallt.
Klingt als Hypothese nicht schlecht
> Dagegen spricht, dass es mit 768 Bytes endlos läuft.
Wieso soll das dagegen sprechen?
Wenn immer wieder sich Lücken auftun, die groß genug sind, dann kann das
ewig so weiter gehen.
Das Problem bei Fragmentierung ist, dass man sehr genau analysieren
müsste, wann welcher Speicher belegt und wann welcher Speicher frei
gegeben wird und wann kleinere nebeneinander liegende freie
Speicherbereiche wieder zu einem größeren zusammengefügt werden.
Aber spricht nicht gegen die Hypothese, dass das Programm nur dann
abstürzt, wenn diese Zeile enthalten ist:
1
if(pathToFile!=file.getPathToFile())
? Oder wird hier tatsächlich auch Speicher angefordert, das ist doch ein
simpler Vergleich?
Gibt es Faustregeln wie groß der Heap sein sollte, oder ist das eine
Gefühlssache? Ich meine wie kann ich jetzt davon ausgehen, dass es ewig
mit 768 Bytes korrekt läuft?
Ruhig Blut. Erstmal solltest du vielleicht überlegen ob dein
"Dateiansatz" auf einem MSP430 wirklich gebräuchlich ist.
Vielleicht erhälst du bei Einblick in den Assembler-Code einen Wink auf
das Bottle-Neck.
Was passiert wenn man testweise den String mal nicht auf dem Heap,
sondern:
-auf dem Stack anlegt (sofern aufgrund des Scopes möglich)?
-als globale Variable (evtl. globales char-Array mit fester Länge)
anlegt?
Mark Brandis schrieb:> Was passiert wenn man testweise den String mal nicht auf dem Heap,> sondern:> -auf dem Stack anlegt (sofern aufgrund des Scopes möglich)?> -als globale Variable (globales char-Array mit fester Länge) anlegt?
Der string sorgt ja intern dafür, dass Speicher angefordert wird, ich
selber lege den string ja auf dem stack an (also kein new).
Die globale Variable mit char-Array wäre meine Notfalllösung, falls das
mit den strings zu unvorherseh bist.
Daher meine Frage: Wie bestimmte ich den Heapspeicher für eine
Anwendung? Gibt es da Richtlinien? Ich habe schon recherchiert, aber der
einzige Ansatz den ich gefunden habe besteht darin, experimentell
herauszufinden, wann der Heap & Stack groß genug ist
Um mich mal selber zu zitieren:
Verbatim schrieb:> Daher meine Frage: Wie bestimmte ich den Heapspeicher für eine> Anwendung? Gibt es da Richtlinien? Ich habe schon recherchiert, aber der> einzige Ansatz den ich gefunden habe besteht darin, experimentell> herauszufinden, wann der Heap & Stack groß genug ist
Ich habe da soeben von IAR eine sehr gute Präsentation gefunden:
1
The first question to be answered when considering an application
2
using dynamic memory is how much heap do I need?
3
4
- This is really more of an estimate than a
5
determination
und
1
It is difficult to estimate how much heap space you will need
2
without some sort of tool to help analyze your dynamic
3
memory needs.
4
5
- There exist such tools for desktop Java (HAT, Heap Analysis Tool)
Verbatim schrieb:> Mark Brandis schrieb:> Die globale Variable mit char-Array wäre meine Notfalllösung, falls das> mit den strings zu unvorherseh bist.>> Daher meine Frage: Wie bestimmte ich den Heapspeicher für eine> Anwendung? Gibt es da Richtlinien? Ich habe schon recherchiert, aber der> einzige Ansatz den ich gefunden habe besteht darin, experimentell> herauszufinden, wann der Heap & Stack groß genug ist
Wenn deine Applikation genug klein ist kannst du den Speicherverbrauch
berechnen, also wenn du weisst du hast max. 3 Strings der länge X, Y und
Z, dann speicher für Daten und Speicher für String Objekt berechnen.
(C++ compiler kann dir ggf. noch mit sizeof(string) etwas weiterhelfen)
Ich würde schätzen bevorzugen;-)
Es gibt aber noch eine andere Möglichkeit, ich weiss aber nicht ob das
auf deinem µC umsetzbar ist, habe sowas noch nie im Mikrocontroller
bereich gemacht.
new und delete überladen, bzw schauen ob du dich irgendwie reinhängen
kannst. Dann kannst du feststellen wie viel Speicher das gebraucht wird,
und ggf. wie gross die Blöcke sind.
Aber auch da bist du nur dann sicher wenn du immer die gleichen Daten
zum verarbeiten hast, also wenn z.B. plötzlich doppelt so lange Strings
von irgendwoher gelesen werden wird natürlich auch meh Speicher
gebraucht, du müsstest also mit dem worst-case testen.
mfg Andreas
Beim Datentype String musst Du aufpassen. Ist ein String einmal
angelegt, ist dieser nicht mehr änderbar. Jede Änderung erzeugt eine
Kopie des String auf dem Heap. Da kann der schnell mal überlaufen. Auf
dem PC ist das, bis auf die Performance, kein Problem. Auf dem
Controller schon.
Grüsse