2012-06-22 11 views
5

En Python 2.7, cuando la carga de todos los datos de un archivo de texto de 2,5 GB en la memoria para un procesamiento más rápido de esta manera:carga Python 2 GB de archivo de texto en la memoria

>>> f = open('dump.xml','r') 
>>> dump = f.read() 

Tengo el siguiente error:

Python(62813) malloc: *** mmap(size=140521659486208) failed (error code=12) 
*** error: can't allocate region 
*** set a breakpoint in malloc_error_break to debug 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
MemoryError 

¿Por qué Python intentó asignar 140521659486208 bytes de memoria para 2563749237 bytes de datos? ¿Cómo arreglo el código para que cargue todos los bytes?

Estoy teniendo alrededor de 3GB de RAM gratis. El archivo es un volcado xml Wiktionary.

+7

¿Por qué no analiza el XML linealmente sin cargar primero la fuente en la memoria? – Alfe

+0

Lo probé y me llevó mucho tiempo. Y como tengo mucha RAM, quiero cargar todo en la RAM para hacerlo más rápido. – pckben

+0

¿Cuánto carnero? 64 o 32 bit? – joslinm

Respuesta

10

Si usa mmap, podrá cargar todo el archivo en la memoria inmediatamente.

import mmap 

with open('dump.xml', 'rb') as f: 
    # Size 0 will read the ENTIRE file into memory! 
    m = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) #File is open read-only 

    # Proceed with your code here -- note the file is already in memory 
    # so "readine" here will be as fast as could be 
    data = m.readline() 
    while data: 
    # Do stuff 
    data = m.readline() 
+0

Obtuve 'mmap.error: [Errno 13] Permiso denegado' para la línea con' m = mmap.mmap (..) ', ¿cómo lo arreglo? – pckben

+2

@pckben Esto se debe a que el archivo está abierto en modo de solo lectura y mmap intentará asignar la lectura y escritura: agregue 'prot = mmap.PROT_READ' en su llamada' mmap.mmap', y estará bien. –

+1

Cool. ¡Funcionó! ¿Te importaría explicar lo que pasó? – pckben

0

Basado en un rápido google, me encontré con this forum post que parece solucionar el problema que parece tener. Suponiendo que está ejecutando Mac o Linux en función del código de error, puede intentar implementar la recolección de basura con gc.enable() o gc.collect() como se sugiere en la publicación del foro.

+0

mi código es tan solo 2 líneas como las dadas para cargar datos en la memoria, no hay otro objeto vivo para la recolección de basura. – pckben

Cuestiones relacionadas