2012-06-22 1 views
5

In Python 2.7, quando carico tutti i dati da un file di testo di 2,5 GB in memoria per l'elaborazione più veloce in questo modo:Python carico 2 GB di file di testo nella memoria

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

ho ottenuto il seguente errore:

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 

Perché Python ha tentato di allocare memoria 140521659486208 byte per i dati di 2563749237 byte? Come aggiusto il codice per far caricare tutti i byte?

Ho circa 3 GB di RAM gratuiti. Il file è un dump di Wikizionario xml.

+7

Perché non analizzare l'XML in modo lineare senza caricare prima la sorgente in memoria? – Alfe

+0

L'ho provato e mi ci è voluto molto tempo. E poiché ho molta RAM, voglio caricare tutto nella RAM per renderlo più veloce. – pckben

+0

Quanto ram? 64 o 32 bit? – joslinm

risposta

10

Se si utilizza mmap, sarà possibile caricare immediatamente l'intero file nella memoria.

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

Ho ottenuto 'mmap.error: [Errno 13] Autorizzazione negata' per la riga con' m = mmap.mmap (..) ', come posso risolverlo? – pckben

+2

@pckben Questo perché il file è aperto in modalità di sola lettura e mmap proverà a mappare read-write: aggiungi 'prot = mmap.PROT_READ' nella tua chiamata' mmap.mmap', e starai bene. –

+1

Fresco. Ha funzionato! Ti andrebbe di spiegare cosa è successo? – pckben

0

Sulla base di alcune ricerche su google, mi sono imbattuto in this forum post che sembra risolvere il problema che sembra avere. Supponendo che tu stia utilizzando Mac o Linux in base al codice di errore, puoi provare a implementare la garbage collection con gc.enable() o gc.collect() come suggerito nel post del forum.

+0

il mio codice è solo 2 righe come indicato per il caricamento dei dati nella memoria, non ci sono altri oggetti viventi per la garbage collection. – pckben