PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] Programm benötigt mehr Speicher als vorhanden


Silpion
2007-04-30, 15:58:47
Hallo,

ich habe ein kleines Problem mit der Speicherverwaltung. Mein Notebook ist mit 1 GB RAM und WinXP Home ausgestattet, die Auslagerungsdatei ist auf 2 GB eingestellt und ich arbeite an einem Programm, das insgesamt ca. 1.5 GB Arbeitsspeicher benötigt.

Dass die Auslagerungsdatei funktioniert kann man daran feststellen, dass das Programm die vorhandenen Daten auslagert, wenn ich z.B. kurz im Internet surfe.

Bisher dachte ich, dass die Auslagerungsdatei für die fehlenden 0.5 GB an Speicher herhalten würde, aber jedesmal, wenn mein Programm an die 1 GB Marke heran kommt, wirft "new" eine Exception.

Gibt es eine Möglichkeit hier weiter zu arbeiten, ohne das Programm so umzuschreiben, dass es weniger Daten im Speicher hält (Geschwindigkeit hat Priorität und der PC auf dem das Programm später laufen wird, wird genug Speicher haben).

AnPapaSeiBua
2007-04-30, 16:05:04
Wie groß sind denn die einzelnen Blöcke, die du anforderst? Zu große Blöcke können aufgrund der Fragmentierung des Addressraums zu so etwas führen.

Silpion
2007-04-30, 16:15:26
Es handelt sich um Volumendaten von mindestens 420 MB bis (bisher) 550 MB.

Ein kurzes Testprogramm stürzt allerdings auch ab, wenn ich erst (erfolgreich) 950 MB anfordere und dann nochmal weitere 100 MB. Für Letztere sollte eigentlich irgendwo in der Auslagerungsdatei auf jeden Fall Platz sein.

AnPapaSeiBua
2007-04-30, 16:17:10
Die 100 MB sollten eigentlich schon gehen. Du kannst aber probehalber mal versuchen, die 1-GB-Grenze per 1-MB-Häppchen zu überschreiten. Wenn das nicht geht, liegt das Problem wo anders.

micki
2007-04-30, 16:20:29
Die 100 MB sollten eigentlich schon gehen. Du kannst aber probehalber mal versuchen, die 1-GB-Grenze per 1-MB-Häppchen zu überschreiten. Wenn das nicht geht, liegt das Problem wo anders.
falls der insgesammt angeforderte speicher von allen programmen+windows ueber 2GB kommt, koennte es sein dass (wie oben schon gesagt) der addressraum ausgegangen ist. also lass sowenig programme wie moeglich laufen wenn du das testest, auch wenn manche wenig speicher verbrauchen, zerschiessen die den adressraum (am besten erst garnicht starten lassen ;) ).

Silpion
2007-04-30, 16:32:35
Mit 1 MB Anforderungen kommt das Programm bis 1.7 GB. Dann scheint die Fragmentierung das das Problem zu sein.

Hmm... ob man das mit variabler Auslagerungsdatei umgehen kann?
*testen geh*

Coda
2007-04-30, 16:33:35
Typischer Fall für eine 64-Bit-Anwendung ;)

micki
2007-04-30, 16:35:23
Mit 1 MB Anforderungen kommt das Programm bis 1.7 GB. Dann scheint die Fragmentierung das das Problem zu sein.

Hmm... ob man das mit variabler Auslagerungsdatei umgehen kann?
*testen geh*vermutlich nicht. mehr als 3GB an speicher sollte ein winxp32 nicht managen koennen, egal wieviel auslagerungsdatei du angibst.

Gast
2007-04-30, 16:50:51
Hallo,

ich habe ein kleines Problem mit der Speicherverwaltung. Mein Notebook ist mit 1 GB RAM und WinXP Home ausgestattet, die Auslagerungsdatei ist auf 2 GB eingestellt und ich arbeite an einem Programm, das insgesamt ca. 1.5 GB Arbeitsspeicher benötigt.

Dass die Auslagerungsdatei funktioniert kann man daran feststellen, dass das Programm die vorhandenen Daten auslagert, wenn ich z.B. kurz im Internet surfe.

Bisher dachte ich, dass die Auslagerungsdatei für die fehlenden 0.5 GB an Speicher herhalten würde, aber jedesmal, wenn mein Programm an die 1 GB Marke heran kommt, wirft "new" eine Exception.

Gibt es eine Möglichkeit hier weiter zu arbeiten, ohne das Programm so umzuschreiben, dass es weniger Daten im Speicher hält (Geschwindigkeit hat Priorität und der PC auf dem das Programm später laufen wird, wird genug Speicher haben).


Mach ein 64bit Programm daraus und lass es mal auf entsprechender Hardware rennen.

AnPapaSeiBua
2007-04-30, 17:04:49
Eigentlich hast du jetzt nur 2 Möglichkeiten:
-Programm umschreiben, so dass kleinere Blöcke angefordert werden
-auf 64 Bit portieren

Silpion
2007-04-30, 17:25:27
Hmm... die Auslagerungsdatei zu vergrößern hat nichts gebracht. Wenn Windows sich so platziert hätte wie bisher, hätte der zusätzliche Speicher locker ausgereicht. Immerhin sind 1.5 GB noch ein Stück von der 4 GB Grenze entfernt. Auf 2 GB RAM aufrüsten hätte vermutlich auch nur den Effekt, dass ein weiteres GB schneller wird, aber an der Fragmentierung würde sich nichts ändern.

Auf 64 bit portieren entfällt, da noch andere Leute an anderen Stellen an der Software arbeiten und vermutlich keiner zur Zeit ein 64bit OS laufen hat.

Dann muss ich wohl die Speicherverwaltung des Programms umschreiben... werd am Mittwoch mal mit meinem Professor und der Arbeitsgruppe darüber sprechen.

Vielen Dank für eure schnelle Hilfe. :)

AnPapaSeiBua
2007-04-30, 17:27:57
Der verfügbare Addressraum pro Anwendung beträgt aber nur 2 GB (standardmäßig), nicht 4. Weiterhin ist es egal, wohin dieser Speicherbereich gemappt wird, der kann im RAM liegen oder auch in der Auslagerungsdatei. Davon sieht deine Anwendung erst mal nix. Auf die Fragmentierung hat das keine Auswirkung.

mickii
2007-04-30, 17:32:22
Hmm... die Auslagerungsdatei zu vergrößern hat nichts gebracht. Wenn Windows sich so platziert hätte wie bisher, hätte der zusätzliche Speicher locker ausgereicht. Immerhin sind 1.5 GB noch ein Stück von der 4 GB Grenze entfernt. Auf 2 GB RAM aufrüsten hätte vermutlich auch nur den Effekt, dass ein weiteres GB schneller wird, aber an der Fragmentierung würde sich nichts ändern.

Auf 64 bit portieren entfällt, da noch andere Leute an anderen Stellen an der Software arbeiten und vermutlich keiner zur Zeit ein 64bit OS laufen hat.

Dann muss ich wohl die Speicherverwaltung des Programms umschreiben... werd am Mittwoch mal mit meinem Professor und der Arbeitsgruppe darüber sprechen.

Vielen Dank für eure schnelle Hilfe. :)
hast du mal meinen tip versucht und alle anderen programme vorher abgeschossen? oder war das eh der fall? :)

AnPapaSeiBua
2007-04-30, 19:26:09
falls der insgesammt angeforderte speicher von allen programmen+windows ueber 2GB kommt, koennte es sein dass (wie oben schon gesagt) der addressraum ausgegangen ist. also lass sowenig programme wie moeglich laufen wenn du das testest, auch wenn manche wenig speicher verbrauchen, zerschiessen die den adressraum (am besten erst garnicht starten lassen ;) ).

Jede Anwendung bekommt seine eigenen 2 GB Addressraum. Von dem, was andere Anwendungen machen, bekommst Du im Addressraum deiner eigenen Anwendung gar nichts mit, die beeinflussen den nicht.

micki
2007-04-30, 22:12:11
Jede Anwendung bekommt seine eigenen 2 GB Addressraum. Von dem, was andere Anwendungen machen, bekommst Du im Addressraum deiner eigenen Anwendung gar nichts mit, die beeinflussen den nicht.
das ist natuerlich humbug. eine 32bit cpu hat nur 32 bit fuer den adressraum (wenn man erweiterungen ueber segmente ausnimmt). dein ganzes system hat also 4gb adressraum. 2gb stehen zur verfuegung, weil ein bit fuer andere dinge verwendet wird (es gibt eine erweiterung bei der dir dann 3GB zur verfuegung stehen).
das ist auch der grund, weshalb du, selbst wenn du 8GB in dein mobo reinsteckst, unter win32 insgesammt nie mehr als 2GB (bzw 3GB) an adressraum bekommst.
bereiche die read only sind, z.b. codesegment (da wo die exe und dlls ihren code reinladen), werden dann auch zwischen anwendungen geteilt. wenn also 10 opengl anwendungen geladen werden, wird nur einmal die DLL in den adressraum gemappt. natuerlich bekommt jede instanz ein eigenes datensegment, aber auch da ist es moeglich einen "shared" speicherbereich einzurichten.
aus diesem grund ist es wichtig moeglichst wenige programme laufen zu lassen wenn du auf 2GB zugreifen willst.
1. der gesammte 32bit bereich wird unter allen programmen aufgeteilt
2. die dlls die geshared werden, werden bei jedem programm in den selben adressraum gemappt wenn moeglich -> fragmentierung.


bitte vermisch den verfuegbaren adressraum nicht mit dem protected mode, das sind zwei verschiede dinge.

Silpion
2007-04-30, 23:01:23
hast du mal meinen tip versucht und alle anderen programme vorher abgeschossen? oder war das eh der fall? :)
Ja, das habe ich probiert. Ich habe grundsätzlich recht wenig Programme laufen, alle Programme und Services beenden bringt bei meinen Datenmengen aber leider nicht mehr viel.

micki
2007-04-30, 23:20:31
Ja, das habe ich probiert. Ich habe grundsätzlich recht wenig Programme laufen, alle Programme und Services beenden bringt bei meinen Datenmengen aber leider nicht mehr viel.

du hast ja gesagt

Es handelt sich um Volumendaten ...
also ne art 3d array?
du kannst dann genausogut ein array von pointern auf 2d-arrays anlegen

und dann musst du zu jedem index ein "new" mit dem 2d array machen.

am ende koennte es sich genau so verhalten (ausser eben das anlegen und deleten).
so musst du dann nicht viel aendern :)

Silpion
2007-04-30, 23:31:51
Ja, momentan ist es ein Array, in dem alle Daten des Volumens stehen.

An so einen Ansatz mit einzelnen Slices habe ich heute auch schon gedacht, allerdings ist das Array allgemein gehalten und kann mit beliebig dimensionalen Daten umgehen (ist zum Glück auf meinem Mist gewachsen, ich kann es also verändern wie ich möchte). Vermutlich werde ich das Array in alle Richtungen zerstückeln, so dass es aus 1 MB großen Würfeln besteht. Aber erst rede ich mit meinem Professor darüber...

AnPapaSeiBua
2007-05-01, 09:00:09
das ist natuerlich humbug. eine 32bit cpu hat nur 32 bit fuer den adressraum (wenn man erweiterungen ueber segmente ausnimmt). dein ganzes system hat also 4gb adressraum. 2gb stehen zur verfuegung, weil ein bit fuer andere dinge verwendet wird (es gibt eine erweiterung bei der dir dann 3GB zur verfuegung stehen).
das ist auch der grund, weshalb du, selbst wenn du 8GB in dein mobo reinsteckst, unter win32 insgesammt nie mehr als 2GB (bzw 3GB) an adressraum bekommst.
bereiche die read only sind, z.b. codesegment (da wo die exe und dlls ihren code reinladen), werden dann auch zwischen anwendungen geteilt. wenn also 10 opengl anwendungen geladen werden, wird nur einmal die DLL in den adressraum gemappt. natuerlich bekommt jede instanz ein eigenes datensegment, aber auch da ist es moeglich einen "shared" speicherbereich einzurichten.
aus diesem grund ist es wichtig moeglichst wenige programme laufen zu lassen wenn du auf 2GB zugreifen willst.
1. der gesammte 32bit bereich wird unter allen programmen aufgeteilt
2. die dlls die geshared werden, werden bei jedem programm in den selben adressraum gemappt wenn moeglich -> fragmentierung.


bitte vermisch den verfuegbaren adressraum nicht mit dem protected mode, das sind zwei verschiede dinge.

Wenn das so wäre, wie du schreibst, wie könnten unter Windows dann mehrere Prozesse zusammen mehr als 2 GB belegen?
Ich rede hier natürlich die ganze Zeit vom virtuellen Addressraum, nur dort ist die Fragmentierung interessant.
Falls Du mir nicht glaubst, kannst Du auch gerne Microsoft fragen ;-)
http://msdn2.microsoft.com/en-us/library/aa366912.aspx

Zitat: "... the system maintains a page map for each process ..."

Das unter 2. stimmt allerdings. Wenn Du eine dll aber benötigst, wird sie sowieso in deinen Adressraum gemappt, auch wenn keine Anwendung vorher sie benötigt hat. Sie kann daher genauso eine Fragmentierung verursachen.

AnPapaSeiBua
2007-05-01, 09:02:02
Hier stand nichts Vernünftiges...