2012-04-16 24 views
10

Ho un database KDB/Q che ha circa ~ 2M di dischi al giorno che consumano circa ~ 2G di memoria. Alla fine del giorno esegue alcuni reportage che eseguono join tra le tabelle e l'output dei risultati in file su disco. Durante il calcolo l'utilizzo della memoria aumenta fino a ~ 15G. Il mio problema è che una volta finita questa operazione, la memoria non viene mai rilasciata e finché il DB non viene riavviato consuma tutto il 15G di memoria.Consumo di memoria KDB/Q

Vorrei dire a KDB di scaricare alcune tabelle dalla memoria (non lasciarle cadere), ma non voglio riavviare il DB poiché alcune altre app ci stanno ancora connettendo.

C'è un modo per dire a KDB di scaricare qualcosa dalla memoria?

EDIT:

Se qualcuno lo trova interessante suggerisco di dare un'occhiata su .Q.gc[] per KDB 2.5+, sembra essere molto promettente.

risposta

7

Qui è la somma up della mia ricerca:

  • KDB prima ver. 2.5 assegna 64 KB di pezzi di memoria in caso di necessità e non li rilascia mai. È in grado di riutilizzarli però.
  • versioni recenti KDB permettono .Q.gc[] conversazione in-richiesta di chiamata al garbage collector (KDB utilizza rif. Contando btw.)
  • questo è particolarmente utile quando si richiama un po 'di calcolo intensivo di memoria che alloca molta memoria (nel mio caso era ~ 20gB) e vuoi rilasciare la memoria al termine del calcolo.
  • si può sempre valutare l'ipotesi di script intensivo di memoria in un processo Q separata in modo che la memoria verrà rilasciato una volta al termine dello script
4

Questo può essere ovvio, ma oltre a controllare le modalità di raccolta dei rifiuti per la versione di q, assicurati di aver effettivamente eliminato i dati in memoria che stanno utilizzando la memoria. Se sei ok con sbarazzarsi di tutta la tabella (ad esempio, si tratta di una tabella temporanea coinvolti nel calcolo), è sufficiente eliminarlo dallo spazio dei nomi radice

delete table from`. 

in caso contrario, è possibile eliminare tutte le righe

delete from`table 
2

per chiunque di provare questo in futuro il modo più semplice sarebbe stato quello di:

  1. avviare un nuovo processo KDB.
  2. Da quella query di processo per selezionare i più piccoli sottoinsiemi di dati limitati necessari.
  3. Eseguire qualsiasi unione/calcolo/scrittura su file da tale processo. (che consente all'originale di continuare le richieste di elaborazione)
  4. Chiudere il processo, liberando tutta la memoria.

Come menzionato dai precedenti manifesti, le versioni più recenti di KDB liberano la memoria meglio ma non sono perfette.

C'è un buon articolo sul nostro sito web della società che i dettagli KDB + Memory Management: http://timestored.com/kdbGuides/memoryManagement

1

http://code.kx.com/q4m3/12_Workspace_Organization/#125-expunging-from-a-context

Ho usato alcuni comandi differenti. Finché la tua tabella viene memorizzata su disco prima di cancellarla, dovresti essere OK.

Questa è la sessione prima di creare la tabella.

q).Q.w[] 
used| 290192 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 629 
symw| 20704 

Questo comando crea la tabella e quindi la salva su disco.

q)t:([]10000?"ab"; 10000?5) 
q)save `t 
`:t 

Il tavolo è ancora in memoria

q).Q.w[] 
used| 437808 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 629 
symw| 20704 

Diamo VENIR MENO L 'variabile da memoria e spazzatura raccogliere.

q)delete t from `. 
`. 
q).Q.gc[] 
0 

Ora la memoria `è stata ridotta ad una quantità simile all'inizio della sessione.

q).Q.w[] 
used| 290208 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 630 
symw| 20730 
q)\v 
`symbol$() 
Problemi correlati