Ich habe 8 GB RAM, aber Haskell-Programme können scheinbar nur 1,3 GB verwenden.
Ich verwende dieses einfache Programm, um zu bestimmen, wie viel Speicher ein GHC-Programm zuordnen kann:
%Vor%Hier ist was ich finde:
./mem.exe 40000000 +RTS -s
erfolgreich und meldet 1113 MB total memory in use
./mem.exe 42000000 +RTS -s
schlägt mit out of memory error
fehl
./mem.exe 42000000 +RTS -s -M4G
Fehlern mit -M4G: size outside allowed range
./mem.exe 42000000 +RTS -s -M3.9G
schlägt mit out of memory error
fehl
Die Überwachung des Prozesses über den Windows Task-Manager zeigt, dass die maximale Speicherbelegung etwa 1,2 GB beträgt.
Mein System: Win7, 8 GB RAM, Haskell Platform 2011.04.0.0, ghc 7.0.4.
Ich kompiliere mit: ghc -O2 mem.hs -rtsopts
Wie kann ich all meinen verfügbaren Arbeitsspeicher nutzen? Fehle ich etwas Offensichtliches?
Derzeit ist GHC unter Windows ein 32-Bit-GHC - ich denke, dass ein 64-Bit-GHC für Windows verfügbar sein wird, wenn 7.6 kommt.
Eine Konsequenz davon ist, dass Sie unter Windows nicht mehr als 4G - 1BLOCK
des Speichers verwenden können, da das Maximum als Größenparameter HS_WORD_MAX
ist:
Mit 32-Bit-Wörtern, HS_WORD_MAX = 2^32-1
.
Das erklärt
running ./mem.exe 42000000 + RTS -s -M4G Fehler mit -M4G: Größe außerhalb des zulässigen Bereichs
seit decodeSize()
dekodiert 4G
als 2^32
.
Diese Einschränkung bleibt auch nach dem Upgrade Ihres GHC bestehen, bis endlich ein 64-Bit GHC für Windows veröffentlicht wird.
Bei einem 32-Bit-Prozess ist der virtuelle Adressraum im Benutzermodus auf 2 oder 4 GB begrenzt (abhängig vom Status des Flags IMAGE_FILE_LARGE_ADDRESS_AWARE
), siehe Speicherlimits für Windows-Versionen .
Nun versuchen Sie, ein Set
mit 42 Millionen 4-Byte Int
s zu erstellen. A Data.Set.Set
hat fünf Overheadwörter pro Element (Konstruktor, Größe, linker und rechter Unterbaumzeiger, Zeiger auf Element), so dass Set
etwa 0,94 GiB Speicher belegt (1.008 'Metrik' GB). Aber der Prozess verwendet etwa doppelt so viel oder mehr (es benötigt Platz für die Garbage-Collection, mindestens die Größe des Live-Heaps).
Ausführen des Programms auf meinem 64-Bit-Linux, mit Eingabe 21000000 (um die doppelt so große Int
s und Zeiger zu ersetzen), bekomme ich
aber top
meldet nur 1.1g
der Speicherbelegung - top
, und vermutlich meldet der Task-Manager nur den Live-Heap.
So scheint es, dass IMAGE_FILE_LARGE_ADDRESS_AWARE
nicht gesetzt ist, Ihr Prozess ist auf einen Adressraum von 2 GB begrenzt und die 42 Mio. Set
brauchen mehr als das - es sei denn, Sie geben eine maximale oder vorgeschlagene Heap-Größe an, die kleiner ist:
Wenn Sie die maximale Größe des Heapspeichers so einstellen, wie sie normalerweise verwendet wird, passt es tatsächlich kaum mehr als der Platzbedarf für Set
, zum Preis einer etwas längeren GC-Zeit und schlägt eine Heapgröße von% co_de vor % lässt es nur mit
Wenn Sie also eine maximale Größe des Heapspeichers unter 2 GB angeben (aber groß genug, damit -H1800M
passt), sollte es funktionieren.
Die Standard-Heap-Größe ist unbegrenzt .
Mit GHC 7.2 auf einem 64-Bit-Windows XP-Rechner kann ich höhere Werte zuweisen, indem ich die Größe des Heapspeichers explizit festlege:
%Vor%und
%Vor%gerade:
%Vor%Das heißt, ich kann dem Windows XP 2G-Prozesslimit zuweisen . Ich stelle mir vor, dass Sie auf Win 7 keine so niedrige Grenze haben werden - diese Tabelle schlägt entweder 4G oder 192G vor - fragen Sie einfach nach soviel Sie benötigen (und verwenden Sie einen neueren GHC).
Tags und Links haskell ghc windows memory-management heap-memory