Ce este Swappiness pe Linux? (și cum se schimbă)

Publicat: 2022-01-29
Stick-uri de memorie cu acces aleatoriu (RAM) pentru un computer.
subin-ch/Shutterstock.com

Valoarea de schimb Linux nu are nimic de-a face cu cât de mult RAM este utilizată înainte de începerea schimbului. Aceasta este o greșeală larg raportată și larg crezută. Vă explicăm ce este cu adevărat.

Dezvăluirea miturilor despre swapiness

Schimbarea este o tehnică prin care datele din memoria cu acces aleatoriu (RAM) sunt scrise într-o locație specială de pe hard disk - fie o partiție de schimb, fie un fișier de schimb - pentru a elibera RAM.

Linux are o setare numită valoarea swappiness. Există multă confuzie cu privire la ceea ce controlează această setare. Cea mai frecventă descriere incorectă a schimbului este că stabilește un prag pentru utilizarea RAM și când cantitatea de RAM utilizată atinge acel prag, începe schimbul.

Aceasta este o concepție greșită care s-a repetat atât de des încât acum este primită înțelepciune. Dacă (aproape) toți ceilalți vă spun că așa funcționează schimbul, de ce să ne credeți când spunem că nu este?

Simplu. O să dovedim.

RAM-ul tău este împărțit în zone

Linux nu consideră RAM-ul tău ca pe un mare bazin omogen de memorie. Consideră că este împărțit într-un număr de regiuni diferite numite zone. Ce zone sunt prezente pe computerul dvs. depinde dacă acesta este pe 32 de biți sau pe 64 de biți. Iată o descriere simplificată a zonelor posibile pe un computer cu arhitectură x86.

  • Acces direct la memorie (DMA) : Aceasta este memoria redusă de 16 MB. Zona își ia numele pentru că, cu mult timp în urmă, existau computere care puteau face doar acces direct la memorie în această zonă a memoriei fizice.
  • Direct Memory Access 32 : În ciuda numelui său, Direct Memory Access 32 (DMA32) este o zonă care se găsește numai în Linux pe 64 de biți. Este cel puțin 4 GB de memorie. Linux care rulează pe computere pe 32 de biți poate face DMA doar pentru această cantitate de RAM (cu excepția cazului în care utilizează nucleul extensiei de adresă fizică (PAE)), așa cum și-a primit numele zona. Deși, pe computerele pe 32 de biți, se numește HighMem.
  • Normal : pe computerele pe 64 de biți, memoria normală este toată memoria RAM de peste 4 GB (aproximativ). Pe mașinile pe 32 de biți, RAM are între 16 MB și 896 MB.
  • HighMem : acesta există doar pe computerele Linux pe 32 de biți. Este toată memoria RAM de peste 896 MB, inclusiv RAM de peste 4 GB pe mașini suficient de mari.

Valoarea PAGESIZE

RAM este alocată în pagini, care au o dimensiune fixă. Dimensiunea respectivă este determinată de nucleu în momentul pornirii prin detectarea arhitecturii computerului. De obicei, dimensiunea paginii pe un computer Linux este de 4 Kbytes.

Publicitate

Puteți vedea dimensiunea paginii dvs. folosind comanda getconf :

 getconf PAGESIZE 

getconf PAGESIZE

Zonele sunt atașate la noduri

Zonele sunt atașate la noduri. Nodurile sunt asociate cu o unitate centrală de procesare (CPU). Nucleul va încerca să aloce memorie pentru un proces care rulează pe un CPU de la nodul asociat cu acel CPU.

Conceptul de noduri legate de procesoare permite instalarea unor tipuri de memorie mixte în calculatoare specializate cu mai multe CPU, folosind arhitectura Acces la memorie non-uniformă.

Toate acestea sunt foarte high-end. Calculatorul mediu Linux va avea un singur nod, numit nod zero. Toate zonele vor aparține nodului respectiv. Pentru a vedea nodurile și zonele din computerul dvs., căutați în /proc/buddyinfo . Vom folosi less pentru a face acest lucru:

 mai puțin /proc/buddyinfo 

Aceasta este rezultatul de la computerul pe 64 de biți pe care a fost cercetat acest articol:

 Nodul 0, zona DMA 1 1 1 0 2 1 1 0 1 1 3
Nodul 0, zona DMA32 2 67 58 19 8 3 3 1 1 1 17
Publicitate

Există un singur nod, nodul zero. Acest computer are doar 2 GB de RAM, deci nu există o zonă „Normală”. Există doar două zone, DMA și DMA32.

Fiecare coloană reprezintă numărul de pagini disponibile de o anumită dimensiune. De exemplu, pentru zona DMA32, citind din stânga:

  • 2 : Există 2 din 2^( 0 *PAGESIZE) bucăți de memorie.
  • 67 : Există 67 din 2^( 1 *PAGE_SIZE) bucăți de memorie.
  • 58 : Există 58 din 2^( 2 *PAGESIZE) bucăți de memorie disponibile.
  • Și așa mai departe, până la...
  • 17 : Există 17 din 2^( 512 *PAGESIZE) bucăți.

Dar într-adevăr, singurul motiv pentru care ne uităm la aceste informații este să vedem relația dintre noduri și zone.

Pagini de fișiere și pagini anonime

Maparea memoriei utilizează seturi de intrări din tabelul de pagini pentru a înregistra ce pagini de memorie sunt utilizate și pentru ce.

Mapările memoriei pot fi:

  • Fișier susținut : mapările susținute de fișiere conțin date care au fost citite dintr-un fișier. Poate fi orice fel de fișier. Lucrul important de reținut este că, dacă sistemul a eliberat această memorie și a avut nevoie să obțină din nou acele date, aceasta poate fi citită încă o dată din fișier. Dar, dacă datele au fost modificate în memorie, acele modificări vor trebui scrise în fișierul de pe hard disk înainte ca memoria să poată fi eliberată. Dacă acest lucru nu s-ar întâmpla, schimbările ar fi pierdute.
  • Anonim : memoria anonimă este o mapare a memoriei fără niciun fișier sau dispozitiv care să o susțină. Aceste pagini pot conține memorie solicitată din mers de programe pentru a stoca date sau pentru lucruri precum stiva și grămada. Deoarece nu există niciun fișier în spatele acestui tip de date, trebuie să fie rezervat un loc special pentru stocarea datelor anonime. Acel loc este partiția de schimb sau fișierul de schimb. Datele anonime sunt scrise pentru a fi schimbate înainte ca paginile anonime să fie eliberate.
  • Dispozitiv susținut : dispozitivele sunt adresate prin blocarea fișierelor dispozitivului care pot fi tratate ca și cum ar fi fișiere. Datele pot fi citite din ei și scrise în ei. O mapare a memoriei susținute de dispozitiv are date de la un dispozitiv stocate în ea.
  • Partajat : mai multe intrări din tabelul de pagini pot fi mapate pe aceeași pagină a memoriei RAM. Accesarea locațiilor de memorie prin oricare dintre mapări va afișa aceleași date. Diferite procese pot comunica între ele într-un mod foarte eficient prin modificarea datelor din aceste locații de memorie urmărite în comun. Mapările scrise partajate sunt un mijloc comun de a realiza comunicații de înaltă performanță între procese.
  • Copiere la scriere : Copierea la scriere este o tehnică de alocare leneșă. Dacă se solicită o copie a unei resurse deja în memorie, cererea este satisfăcută prin returnarea unei mapari la resursa originală. Dacă unul dintre procesele care „partajează” resursa încearcă să scrie în ea, resursa trebuie să fie cu adevărat replicată în memorie pentru a permite modificările aduse noii copii. Deci alocarea memoriei are loc doar la prima comandă de scriere.

Pentru schimb, trebuie să ne preocupăm doar de primele două din listă: pagini de fișiere și pagini anonime.

Schimbătură

Iată descrierea swappiness din documentația Linux de pe GitHub:

Publicitate

"This control is used to define how aggressive (sic) the kernel will swap memory pages. Higher values will increase aggressiveness, lower values decrease the amount of swap. A value of 0 instructs the kernel not to initiate swap until the amount of free and file-backed pages is less than the high water mark in a zone.

The default value is 60."

Asta sună ca și cum schimbul transformă schimbul în sus sau în jos în intensitate. Interesant este că se afirmă că setarea swappiness la zero nu dezactivează schimbul. Acesta indică nucleului să nu schimbe până când sunt îndeplinite anumite condiții. Dar schimbul poate avea loc totuși.

Să săpăm mai adânc. Iată definiția și valoarea implicită a vm_swappiness în fișierul de cod sursă al nucleului vmscan.c:

/*
* From 0 .. 100. Higher means more swappy.
*/
int vm_swappiness = 60;

Valoarea de schimb poate varia de la 0 la 100. Din nou, comentariul sună cu siguranță ca și cum valoarea de schimb are o influență asupra numărului de schimburi, cu o cifră mai mare ducând la mai multe schimburi.

Mai departe, în fișierul cod sursă, putem vedea că unei noi variabile numite swappiness i se atribuie o valoare care este returnată de funcția mem_cgroup_swappiness() . Mai multe urmăriri prin codul sursă vor arăta că valoarea returnată de această funcție este vm_swappiness . Deci, acum, variabila swappiness este setată să fie egală cu orice valoare la care a fost setată vm_swappiness .

int swappiness = mem_cgroup_swappiness(memcg);

Publicitate

Și puțin mai jos, în același fișier de cod sursă, vedem asta:

/*
* With swappiness at 100, anonymous and file have the same priority.
* This scanning priority is essentially the inverse of IO cost.
*/
anon_prio = swappiness;
file_prio = 200 - anon_prio;

Interesant. Două valori distincte sunt derivate din swappiness . anon_prio și file_prio dețin aceste valori. Pe măsură ce unul crește, celălalt scade și invers .

Valoarea de swappiness Linux stabilește de fapt raportul dintre două valori.

Raportul de aur

Paginile de fișiere conțin date care pot fi recuperate cu ușurință dacă acea memorie este eliberată. Linux poate citi fișierul din nou. După cum am văzut, dacă datele fișierului au fost modificate în RAM, acele modificări trebuie să fie scrise în fișier înainte ca pagina fișierului să poată fi eliberată. Dar, în orice caz, pagina fișierului din RAM poate fi repopulată citind datele din fișier. Deci, de ce să vă deranjați să adăugați aceste pagini la partiția de swap sau fișierul de swap? Dacă aveți nevoie din nou de acele date, ați putea la fel de bine să le citiți înapoi din fișierul original în loc de o copie redundantă în spațiul de swap. Deci paginile fișierelor nu sunt stocate în swap. Sunt „stocate” înapoi în fișierul original.

Cu paginile anonime, nu există niciun fișier de bază asociat cu valorile din memorie. Valorile din acele pagini au fost atinse dinamic. Nu le puteți citi pur și simplu înapoi dintr-un fișier. Singurul mod în care valorile memoriei de pagină anonime pot fi recuperate este stocarea datelor undeva înainte de a elibera memoria. Și asta înseamnă schimbul. Pagini anonime la care va trebui să le referiți din nou.

Publicitate

Dar rețineți că atât pentru paginile de fișiere, cât și pentru paginile anonime, eliberarea memoriei poate necesita o scriere pe hard disk. Dacă datele paginii fișierului sau datele paginii anonime s-au schimbat de când au fost scrise ultima dată în fișier sau pentru a schimba, este necesară o scriere a sistemului de fișiere. Pentru a prelua datele va fi nevoie de citirea unui sistem de fișiere. Ambele tipuri de revendicare a paginii sunt costisitoare. Încercarea de a reduce intrarea și ieșirea pe hard disk prin minimizarea schimbului de pagini anonime nu face decât să mărească cantitatea de intrare și ieșire pe hard disk necesară pentru a face față paginilor de fișiere scrise și citite din fișiere.

După cum puteți vedea din ultimul fragment de cod, există două variabile. Unul numit file_prio pentru „prioritate fișier”, iar unul numit anon_prio pentru „prioritate anonimă”.

  • Variabila anon_prio este setată la valoarea de swappiness Linux.
  • Valoarea file_prio este setată la 200 minus valoarea anon_prio .

Aceste variabile dețin valori care funcționează în tandem. Dacă ambele sunt setate la 100, sunt egale. Pentru orice alte valori, anon_prio va scădea de la 100 la 0, iar file_prio va crește de la 100 la 200. Cele două valori se alimentează într-un algoritm complicat care determină dacă nucleul Linux rulează cu preferință pentru recuperarea (eliberarea) paginilor de fișiere sau anonim. pagini.

Vă puteți gândi la file_prio ca fiind dorința sistemului de a elibera pagini de fișiere și anon_prio ca dorința sistemului de a elibera pagini anonime. Ceea ce nu fac aceste valori este să seteze orice fel de declanșator sau prag pentru când va fi folosit swap-ul. Asta se hotărăște în altă parte.

Dar, atunci când memoria trebuie eliberată, aceste două variabile – și raportul dintre ele – sunt luate în considerare de algoritmii de recuperare și de schimb pentru a determina ce tipuri de pagini sunt luate în considerare de preferință pentru eliberare. Și asta dictează dacă activitatea asociată pe hard disk va fi procesarea fișierelor pentru paginile de fișiere sau spațiul de schimb pentru pagini anonime.

Când se întrerupe de fapt schimbul?

Am stabilit că valoarea de swappiness Linux stabilește o preferință pentru tipul de pagini de memorie care vor fi scanate pentru o potențială recuperare. E în regulă, dar ceva trebuie să decidă când va interveni schimbul.

Publicitate

Fiecare zonă de memorie are o linie de apă mare și una de apă scăzută. Acestea sunt valori derivate de sistem. Sunt procente ale memoriei RAM din fiecare zonă. Aceste valori sunt folosite ca praguri de declanșare a schimbului.

Pentru a verifica care sunt semnele de apă ridicate și scăzute, priviți în interiorul /proc/zoneinfo cu această comandă:

 mai puțin /proc/zoneinfo 

Fiecare dintre zone va avea un set de valori de memorie măsurate în pagini. Iată valorile pentru zona DMA32 de pe mașina de testare. Marca de apă scăzută este de 13966 de pagini, iar marca de apă maximă este de 16759 de pagini:

  • În condiții normale de funcționare, când memoria liberă dintr-o zonă scade sub limita de apă scăzută a zonei, algoritmul de schimb începe să scaneze paginile de memorie în căutarea memoriei pe care o poate recupera, ținând cont de valorile relative ale anon_prio și file_prio .
  • Dacă valoarea de schimb pentru Linux este setată la zero, schimbarea are loc atunci când valoarea combinată a paginilor de fișiere și a paginilor libere este mai mică decât limita maximă.

Deci, puteți vedea că nu puteți utiliza valoarea de swappiness Linux pentru a influența comportamentul swap-ului în ceea ce privește utilizarea RAM. Pur și simplu nu funcționează așa.

La ce ar trebui să fie setat Swapiness?

Acest lucru depinde de hardware, volumul de lucru, tipul de hard disk și dacă computerul dvs. este un desktop sau un server. Evident, acesta nu va fi o dimensiune unică pentru toate tipurile de setare.

Și trebuie să aveți în vedere că schimbul nu este folosit doar ca un mecanism pentru a elibera RAM atunci când rămâneți fără spațiu de memorie. Schimbarea este o parte importantă a unui sistem care funcționează bine și, fără el, gestionarea corectă a memoriei devine foarte dificil de realizat pentru Linux.

Publicitate

Schimbarea valorii de swappiness Linux are un efect instantaneu; nu trebuie să reporniți. Astfel, puteți face mici ajustări și puteți monitoriza efectele. În mod ideal, ați face acest lucru pe o perioadă de câteva zile, cu diferite tipuri de activitate pe computer, pentru a încerca să găsiți cea mai apropiată setare ideală.

Acestea sunt câteva puncte de luat în considerare:

  • Încercarea de a „dezactiva schimbul” prin setarea valorii de schimb Linux la zero, pur și simplu schimbă activitatea de hard disk asociată schimbului la activitatea de hard disk asociată fișierelor.
  • Dacă aveți hard disk-uri mecanice vechi, ați putea încerca să reduceți valoarea de schimb pentru Linux pentru a evita recuperarea paginilor anonime și pentru a reduce rata de schimbare a partițiilor de schimb. Desigur, pe măsură ce reduceți o setare, cealaltă setare crește. Reducerea ratei swap poate crește rata de pierdere a sistemului de fișiere. Dar computerul dvs. ar putea fi mai fericit dacă preferă o metodă în detrimentul celeilalte. Într-adevăr, singura modalitate de a ști cu siguranță este să încerci și să vezi.
  • Pentru serverele cu un singur scop, cum ar fi serverele de baze de date, puteți obține îndrumări de la furnizorii de software de bază de date. Foarte des, aceste aplicații au propriile lor cache de fișiere concepute special și rutine de gestionare a memoriei pe care ar fi mai bine să te bazezi. Furnizorii de software pot sugera o valoare de schimb Linux în funcție de specificațiile mașinii și volumul de lucru.
  • Pentru utilizatorul mediu de desktop cu hardware destul de recent? Lasă-o așa cum este.

Cum să setați valoarea Linux Swappiness

Înainte de a vă schimba valoarea de schimb, trebuie să știți care este valoarea sa actuală. Dacă doriți să o reduceți puțin, întrebarea este puțin mai mică decât ce? Puteți afla cu această comandă:

 cat /proc/sys/vm/swappiness 

cat /proc/sys/vm/swappiness

Pentru a configura valoarea swappiness, utilizați comanda sysctl :

 sudo sysctl vm.swappiness=45 

Noua valoare este utilizată imediat, nu este necesară repornirea.

De fapt, dacă reporniți, valoarea de swappiness va reveni la valoarea implicită de 60. După ce ați terminat de experimentat și ați decis noua valoare pe care doriți să o utilizați, o puteți face persistentă în timpul repornirilor adăugând-o la /etc/sysctl.conf fișier. Puteți folosi orice editor preferați. Utilizați următoarea comandă pentru a edita fișierul cu editorul nano :

 sudo nano /etc/sysctl.conf 

Când nano se deschide, derulați până în partea de jos a fișierului și adăugați această linie. Folosim 35 ca valoare permanentă de schimb. Ar trebui să înlocuiți valoarea pe care doriți să o utilizați.

 vm.swappiness=35 

Pentru a salva modificările și a ieși din nano , apăsați „Ctrl+O”, apăsați „Enter” și apăsați „Ctrl+Z”.

Managementul memoriei este complex

Gestionarea memoriei este complicată. Și de aceea, pentru utilizatorul obișnuit, este, de obicei, mai bine să-l lași pe seama nucleului.

Publicitate

Este ușor să crezi că folosești mai multă memorie RAM decât ești. Utilități precum top și free pot da o impresie greșită. Linux va folosi RAM liberă pentru o varietate de scopuri proprii, cum ar fi stocarea în cache pe disc. Acest lucru crește artificial cifra de memorie „folosită” și reduce cifra de memorie „liberă”. De fapt, memoria RAM folosită ca cache pe disc este semnalată atât ca „utilizată” cât și ca „disponibilă”, deoarece poate fi recuperată oricând, foarte rapid.

Pentru cei neinițiați, care ar putea părea ca schimbul nu funcționează sau că valoarea de schimb trebuie schimbată.

Ca întotdeauna, diavolul este în detaliu. Sau, în acest caz, demonul. Daemonul de schimb de nucleu.

LEGATE: Cele mai bune laptopuri Linux pentru dezvoltatori și entuziaști