Actualmente, en Windows, GHC es un GHC de 32 bits; creo que se supone que un GHC de 64 bits para Windows estará disponible cuando llegue 7.6.
Una consecuencia de ello es que en Windows, no se puede utilizar más de 4G - 1BLOCK
de la memoria, ya que el máximo permitido como un parámetro de tamaño es HS_WORD_MAX
:
decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX)/BLOCK_SIZE;
con palabras de 32 bits, HS_WORD_MAX = 2^32-1
.
que explica
corriendo ./mem.exe 42000000 + RTS -s errores -M4G a cabo con -M4G: tamaño fuera del rango permitido
desde decodeSize()
decodifica 4G
como 2^32
.
Esta limitación se mantendrá también después de actualizar su GHC, hasta que finalmente se libere un GHC de 64 bits para Windows.
Como un proceso de 32 bits, el espacio de direcciones virtuales en modo de usuario está limitado a 2 o 4 GB (según el estado de la bandera IMAGE_FILE_LARGE_ADDRESS_AWARE
), cf Memory limits for Windows Releases.
Ahora, intenta construir un Set
que contiene 42 millones de 0 bytes Int
s. Un Data.Set.Set
tiene cinco palabras de sobrecarga por elemento (constructor, tamaño, puntero del subárbol izquierdo y derecho, puntero al elemento), por lo que el Set
ocupará aproximadamente 0,94 GiB de memoria (1,008 'métrico' GB). Pero el proceso utiliza aproximadamente el doble o más (necesita espacio para la recolección de basura, al menos el tamaño del montón dinámico).
Ejecutar el programa en mi Linux de 64 bits, con entrada de 21 millones (para compensar el doble de grande Int
s y punteros), consigo
$ ./mem +RTS -s -RTS 21000000
min: 0
max: 21000000
31,330,814,200 bytes allocated in the heap
4,708,535,032 bytes copied during GC
1,157,426,280 bytes maximum residency (12 sample(s))
13,669,312 bytes maximum slop
2261 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 59971 colls, 0 par 2.73s 2.73s 0.0000s 0.0003s
Gen 1 12 colls, 0 par 3.31s 10.38s 0.8654s 8.8131s
INIT time 0.00s ( 0.00s elapsed)
MUT time 12.12s (13.33s elapsed)
GC time 6.03s (13.12s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 18.15s (26.45s elapsed)
%GC time 33.2% (49.6% elapsed)
Alloc rate 2,584,429,494 bytes per MUT second
Productivity 66.8% of total user, 45.8% of total elapsed
pero top
informes solamente 1.1g
de la memoria use - top
, y presumiblemente el Administrador de tareas, informa solo el montón en vivo.
por lo que parece IMAGE_FILE_LARGE_ADDRESS_AWARE
no está definida, el proceso está limitado a un espacio de direcciones de 2 GB, y los 42 millones de Set
necesita más que eso - a menos que especifique un tamaño máximo de almacenamiento dinámico o sugerido que es más pequeño:
$ ./mem +RTS -s -M1800M -RTS 21000000
min: 0
max: 21000000
31,330,814,200 bytes allocated in the heap
3,551,201,872 bytes copied during GC
1,157,426,280 bytes maximum residency (12 sample(s))
13,669,312 bytes maximum slop
1154 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 59971 colls, 0 par 2.70s 2.70s 0.0000s 0.0002s
Gen 1 12 colls, 0 par 4.23s 4.85s 0.4043s 3.3144s
INIT time 0.00s ( 0.00s elapsed)
MUT time 11.99s (12.00s elapsed)
GC time 6.93s ( 7.55s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 18.93s (19.56s elapsed)
%GC time 36.6% (38.6% elapsed)
Alloc rate 2,611,793,025 bytes per MUT second
Productivity 63.4% of total user, 61.3% of total elapsed
Al establecer el tamaño de pila máximo por debajo de lo que usaría naturalmente, deja que quepa en poco más que el espacio necesario para Set
, al precio de un tiempo de GC un poco más largo, y sugiere un tamaño de montón de -H1800M
para finalizar utilizando solo
1831 MB total memory in use (0 MB lost due to fragmentation)
Por lo tanto, si especifica un tamaño de almacenamiento dinámico máximo inferior a 2 GB (pero lo suficientemente grande como para que quepa el Set
), debería funcionar.
Actualiza a una versión más reciente de GHC. ¿Tiene un límite de proceso máximo establecido en su máquina de Windows? GHC no tiene límites de almacenamiento dinámico, por lo que es probable que el sistema operativo limite el espacio de direcciones de su proceso. –
Si no desea abandonar la zona de comodidad de utilizar la plataforma Haskell, tenga en cuenta que la próxima versión se lanzará este mes; La última vez que lo revisé iba a incluir GHC 7.4.1. – dave4420