Ho un'applicazione in cui l'intero database è implementato in memoria utilizzando una stl-map per ogni tabella nel database.Come ottimizzare il paging per database di grandi dimensioni in memoria
Ogni elemento nella stl-map è un oggetto complesso con riferimenti ad altri elementi nelle altre mappe stl.
L'applicazione funziona con una grande quantità di dati, quindi utilizza più di 500 MB di RAM. I client sono in grado di contattare l'applicazione e ottenere una versione filtrata dell'intero database. Ciò avviene eseguendo l'intero database e individuando elementi pertinenti per il cliente.
Quando l'applicazione è in esecuzione da un'ora o giù di lì, Windows 2003 SP2 inizia a pagina delle parti della RAM per l'applicazione (anche se sulla macchina è presente una RAM da 16 GByte).
Dopo che l'applicazione è stata parzialmente ignorata, l'accesso al client richiede molto tempo (10 minuti) perché ora genera un errore di pagina per ogni ricerca di puntatori nella mappa stl. Se si esegue l'accesso client una seconda volta subito dopo, è veloce (alcuni secondi) perché tutta la memoria è ora di nuovo nella RAM.
Vedo che è possibile dire a Windows di bloccare la memoria nella RAM, ma in genere è consigliabile solo per i driver di periferica e solo per "piccole" quantità di memoria.
Immagino che una soluzione povera potrebbe essere quella di scorrere l'intero database di memoria, e quindi dire a Windows che siamo ancora interessati a mantenere il datamodel nella RAM.
Immagino che un'altra soluzione povera potrebbe essere disabilitare completamente il file di paging su Windows.
Suppongo che la soluzione costosa sia un database SQL e quindi riscrivi l'intera applicazione per utilizzare un livello di database. Quindi si spera che il sistema di database abbia implementato i mezzi per un accesso rapido.
Ci sono altre soluzioni più eleganti?
L'applicazione viene eseguita come servizio Windows, ma hanno ancora una finestra di console (Usi AllocConsole). Mi chiedo se Windows reagisce a questa finestra della console che viene ridotta a icona, quindi decide di tagliare il working set. –
Si è inoltre notato che molti buffer di lavoro sono stati allocati utilizzando new o malloc ma senza utilizzare una dimensione di blocco uniforme (questa è una vecchia applicazione). Regolando la dimensione dell'allocazione per essere divisibile per 1024, quindi dimezza i byte virtuali per l'applicazione. –
Hanno ora utilizzato ProcDump per registrare le tracce dello stack quando era molto occupato. Ha rivelato che ha trascorso molto tempo su molte grandi nuove operazioni/malloc. Ora ho implementato un migliore riutilizzo del buffer, ma sono ancora perplesso sul motivo per cui il primo accesso al client richiede tempo e la seconda volta è veloce. –