Perché discutere di & # 8220; swappiness & # 8221; agire come se le informazioni potessero essere solo in un posto alla volta?

StackOverflow https://stackoverflow.com/questions/147125

Domanda

Ho letto su "swappiness" di Linux " sintonizzabile, che controlla quanto sia aggressivo il kernel nello scambiare la memoria delle applicazioni su disco quando non vengono utilizzate. Se si utilizza Google il termine, si ottengono molte pagine come this discutere i pro e i contro. In breve, l'argomento va così:

  

Se lo swappiness è troppo basso, le applicazioni inattive porteranno tutta la memoria di sistema che altri programmi potrebbero voler usare.

     

Se la tua swappiness è troppo elevata, quando riattivi quelle applicazioni inattive, ci sarà un grande ritardo poiché il loro stato viene letto dal disco.

Questo argomento non ha senso per me. Se ho un'applicazione inattiva che utilizza una tonnellata di memoria, perché il kernel non memorizza la sua memoria su disco e lascia in memoria un'altra copia di quei dati? Questo sembra dare il meglio di entrambi i mondi: se un'altra applicazione ha bisogno di quella memoria, può immediatamente rivendicare la RAM fisica e iniziare a scriverla, poiché un'altra copia è su disco e può essere sostituita quando l'applicazione inattiva viene svegliata su. E quando l'app originale si riattiva, tutte le sue pagine che sono ancora nella RAM possono essere utilizzate così come sono, senza doverle estrarre dal disco.

O mi sto perdendo qualcosa?

È stato utile?

Soluzione

Secondo questo 1 questo è esattamente ciò che Linux lo fa.

Sto ancora cercando di dare un senso a molto di questo, quindi qualsiasi link autorevole sarebbe apprezzato.

Altri suggerimenti

  

Se ho un'applicazione inattiva che utilizza una tonnellata di memoria, perché il kernel non carica la pagina della sua memoria su disco e lascia in memoria un'altra copia di quei dati?

Diciamo che l'abbiamo fatto. Abbiamo scritto la pagina su disco, ma l'abbiamo lasciata in memoria. Qualche tempo dopo un altro processo ha bisogno di memoria, quindi vogliamo eliminare la pagina dal primo processo.

Dobbiamo sapere con assoluta certezza se il primo processo ha modificato la pagina da quando è stata scritta su disco. Se lo è, dobbiamo scriverlo di nuovo. Il modo in cui lo seguiremmo è quello di togliere il permesso di scrittura del processo alla pagina quando lo abbiamo scritto per la prima volta sul disco. Se il processo tenta di scrivere nuovamente sulla pagina, si verificherà un errore di pagina. Il kernel può notare che il processo ha sporcato la pagina (e dovrà quindi essere riscritto) prima di ripristinare il permesso di scrittura e consentire all'applicazione di continuare.

Qui sta il problema. Togliere l'autorizzazione alla scrittura dalla pagina è in realtà un po 'costoso, in particolare nelle macchine multiprocessore. È importante che tutte le CPU eliminino la cache delle traduzioni delle pagine per assicurarsi di togliere il permesso di scrittura.

Se il processo scrive sulla pagina, prendere un errore di pagina è ancora più costoso. Presumo che un numero non banale di queste pagine finirebbe col prendere quell'errore, che si nutre dei guadagni che stavamo cercando lasciandolo in memoria.

Quindi vale la pena farlo? Onestamente non lo so. Sto solo cercando di spiegare perché lasciare la pagina in memoria non è una vittoria così ovvia come sembra.

(*) Tutto questo è molto simile a un meccanismo chiamato Copy-On-Write, che viene utilizzato quando un fork di processo (). Molto probabilmente il processo figlio eseguirà solo alcune istruzioni e chiamerà exec (), quindi sarebbe sciocco copiare tutte le pagine dei genitori. Invece il permesso di scrittura viene tolto e il bambino può semplicemente correre. Copy-On-Write è una vittoria perché l'errore di pagina non viene quasi mai rilevato: il bambino chiama quasi sempre exec () immediatamente.

Anche se paghi la memoria delle app su disco e la tieni in memoria, dovresti comunque decidere quando un'applicazione deve essere considerata "inattiva". ed è ciò che controlla la swapiness. Il paging su disco è costoso in termini di I / O e non si desidera farlo troppo spesso. C'è anche un'altra variabile su questa equazione, ed è il fatto che Linux usa la memoria rimanente come buffer / cache del disco.

La prima cosa che fa la VM è pulire le pagine e spostarle nell'elenco pulito.
Quando si pulisce la memoria anonima (cose che non hanno un vero archivio di backup dei file, è possibile vedere i segmenti in / proc // maps che sono anonimi e non hanno una memoria vnode del filesystem dietro di loro), la prima cosa che la VM sta per fare è prendi il "sporco" pagine e "pulito" quindi scrivendo il contenuto della pagina per scambiarlo. Ora, quando la VM ha una carenza di memoria completamente libera ed è preoccupata per la sua capacità di concedere nuove pagine gratuite da utilizzare, può passare attraverso l'elenco di pagine "pulite" e in base a quanto recentemente sono state utilizzate e che tipo di memoria loro sono che sposterà quelle pagine nella lista libera.

Dopo che le pagine di memoria sono state inserite nell'elenco libero, non sono più associate ai contenuti che avevano prima. Se un programma presenta un riferimento alla posizione di memoria che la pagina stava servendo in precedenza, il programma subirà un grave errore e una pagina (molto probabilmente completamente diversa) verrà catturata dall'elenco libero e i dati verranno letti nella pagina dal disco. Una volta fatto ciò, la pagina è in realtà ancora 'pulita' poiché non è stata modificata. Se la VM scegliesse di utilizzare quella pagina su swap per una pagina diversa nella RAM, la pagina sarebbe di nuovo 'sporcata', o se l'app scrivesse a quella pagina sarebbe 'sporcata'. E poi il processo ricomincia.

Inoltre, lo swappinness è piuttosto orribile per le applicazioni server in un ambiente aziendale / transazionale / online / sensibile alla latenza. Quando ho 16 GB di RAM in cui non eseguo molti browser e GUI, in genere voglio che tutte le mie app siano quasi bloccate in memoria. La maggior parte della mia RAM tende ad essere un mucchio di java di 8-10 GB che io MAI voglio mai impaginare su disco, e la cruft che è disponibile sono processi come mingetty (ma anche lì le pagine glibc in quelle app sono condivisi da altre app e effettivamente utilizzati, quindi anche le dimensioni RSS di quei processi inutili sono per lo più pagine condivise e utilizzate). Normalmente non vedo più di qualche 10 MB dei 16 GB effettivamente ripuliti per lo scambio. Vorrei consigliare numeri di swapiness molto, molto bassi o zero swapiness per i server: le pagine inutilizzate dovrebbero essere una piccola frazione della RAM complessiva e cercare di recuperare che una quantità relativamente piccola di RAM per la cache del buffer rischia di scambiare pagine dell'applicazione e subire hit di latenza in l'app in esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top