Ferestre - - - Russinovich marca în limba rusă

De data asta am de gând să se uite în punerea în aplicare a tag-uri pentru a găsi și să explice restricțiile existente pentru ei. Descriptori - Această structură de date, care reprezintă instanțele de bază deschise ale obiectelor din sistemul de operare, care interacționează cu aplicația; de exemplu, fișiere, chei de registry, primitivele de sincronizare și de memorie partajată. Există două limitări asociate cu numărul de mânere pe care un proces poate crea: numărul maxim de mânere pe care sistemul poate fi setat pentru proces, iar cantitatea de memorie disponibilă pentru stocarea etichete și obiecte pe care aplicația se conectează la descriptorii lor.

În cele mai multe cazuri, aceste restricții descriptori sunt departe de aceste valori, care sunt frecvent utilizate de aplicații sau de sistem. Cu toate acestea, aplicarea, din care proiectarea nu este luată în considerare aceste limitări, pot avea acces la căile lor neașteptate pentru dezvoltatori. Cel mai adesea, aceste probleme apar din faptul că durata de viață a resursei ar trebui să fie gestionate aplicații, și, la fel ca în cazul de gestionare a memoriei virtuale resursele de sarcini vieti este un fel de provocare chiar si pentru cei mai buni dezvoltatori. O aplicație care nu este în măsură să elibereze resursele neutilizate, care le determină să se scurgă, care, în cele din urmă, poate duce la faptul că se atinge limita de utilizare a unei resurse, rezultând într-un ciudat și dificil de diagnosticat un comportament de acest fel, și alte aplicații, sau întreaga sistem ca întreg.

obiecte descriptori

Ferestre - - - Russinovich marca în limba rusă

Atunci când o aplicație dorește să preia controlul asupra uneia dintre aceste resurse, trebuie să primul apel corespunzătoare API-ul, pentru a crea sau a deschide resursa. De exemplu, funcția CreateFile se deschide sau creează un fișier, funcția RegOpenKeyEx deschide o cheie de registru și funcția CreateSemaporeEx se deschide sau creează un semafor. Dacă această funcție reușește, Windows alocă un mâner la tabelul descriptor proces de aplicare și returnează valoarea descriptorului că cererea se ocupă în mod implicit, dar, de fapt, este vorba despre indicele returnat descriptor în tabelul descriptor.
Cu acces la cererile de aplicare mâner și gestionează obiect, care trece valoarea mâner în funcțiile API astfel, ca ReadFile. SetEvent. SetThreadPriority și MapViewOfFile. Sistemul poate organiza căutarea pentru obiectul la care se referă descriptorului prin tabelul de indexare mâner pentru a localiza descriptorul de înregistrare corespunzătoare, care conține un pointer la obiect. Înregistrarea descriptor stochează de asemenea, informații despre tranzacțiile care au devenit disponibile la proces, așa cum a deschis instalația, care permite sistemului să se asigure că procesul nu va fi capabil să efectueze operații asupra obiectului, care în acest proces nu are permisiunea. De exemplu, în cazul în care procesul este deschis cu succes un fișier pentru citire, intrarea mânerul ar arata ceva de genul:

Ferestre - - - Russinovich marca în limba rusă

În cazul în care acest proces ar încerca să scrie ceva în fișierul, funcția a finalizat executarea unei erori, deoarece acest tip de acces la dosar nu a fost acordat, precum și faptul că accesul cache pentru citire înseamnă că sistemul nu trebuie să se repete din nou, mai costisitoare din punctul de vedere al resurselor de inspecție drepturi de acces.

Numărul maxim de descriptori
Pentru a investiga prima restricție, puteți utiliza instrumentul de Testlimit, pe care l-am folosit în cadrul acestei serii pentru a examina empiric restricțiile privind resursele sistemului. Acesta poate fi descărcat de pe pagina Windows aici Internals. Pentru a determina numărul de descriptori care pot crea procesul, de Testlimit utilizat cu -h, care spune că pentru a crea cât mai multe etichete posibil. Aceasta se realizează prin crearea obiectului evenimentului folosind funcția CreateEvent și ulterioară descriptor sistem duplicarea repetată a revenit prin intermediul funcției DuplicateHandle. Folosind duplicarea, a Testlimit evită necesitatea de a crea noi caracteristici și toate resursele consumate de aceste instrumente sunt cheltuite pentru intrările de masă mâner. Aici este rezultatul Testlimit lucra cu opțiunea -h pe un sistem pe 64 de biți

Ferestre - - - Russinovich marca în limba rusă

Acest rezultat, cu toate acestea, nu reflectă numărul total de descriptori, un proces poate crea ca bibliotecile de sistem DLL deschide diferite obiecte în timpul procesului de inițializare. Numărul total de tag-uri de proces, puteți vedea, adăugând coloana corespunzătoare din Task Manager sau Process Explorer. Cifra totală de Testlimit în acest caz este 16'771'680:

Când executați Testlimit sistem pe 32 de biți, numărul de descriptori va fi puțin diferit:

Numărul total de descriptori și un alt 16744448:

Care sunt cauzate de aceste diferențe? Răspunsul este că sistemul de acționare, care este responsabil pentru tabelul descriptor de gestionare, stabilește o limită a numărului de descriptori pentru fiecare proces, și, de asemenea, cu privire la dimensiunea intrărilor în tabelul descriptor. Aici avem de-a face cu unul dintre acele cazuri rare, in vreme ce Windows stabilește o limită greu pe utilizarea resurselor, astfel încât, în acest caz, executivul, sistemul determină numărul de 16777216 (16 * 1024 * 1024) ca numărul maxim de mânere, care pot fi alocate procesului. Orice proces care este mai mult de zece mii de descriptori simultan în orice moment, foarte probabil, nu are deficiențe grave comise în scurgeri de design sau de mâner. Așa că limita de 16 milioane mânere practic imposibil de atins și este proiectat pentru a ajuta la prevenirea scurgerilor de memorie cauzate de interferențe în procesul de lucru de restul sistemului. Pentru a înțelege motivul pentru care numărul afișat în Task Manager este diferit de maxim hard-set, trebuie să ia în considerare modul în care sistemul executiv organizează mâner tabele.

tabel descriptor de înregistrare trebuie să fie suficient de mare pentru a stoca o mască a drepturilor de acces și un indicator obiect. Masca de acces este o dimensiune pointer pe 32 de biți, dar, evident, depinde de faptul dacă sistemul este pe 32 de biți sau 64 de biți. Prin urmare, intrarea mânerul este de 8 biți pe 32 de biți pentru Windows și 12-biți pe 64 de biți pentru Windows. 64-biți pentru Windows completează structura etichetei de înregistrare a datelor de până la limitele pe 64 de biți, astfel încât eticheta de înregistrare pe 64 de biți are de fapt 16 bytes. Aici este definiția de descriptori de înregistrare pe 64 de biți pentru Windows, afișat în depanatorul kernel cu comanda dt (tipul haldei)

Ferestre - - - Russinovich marca în limba rusă

Aici vedem că structura conține și alte informații, în plus față de o mască pointer obiect și de acces izolate pe captura de ecran.

Sistemul Actionari plasează tabelul de descriptori din blocuri având o dimensiune de pagină, care se împarte în intrările din tabelul de descriptor. Acest lucru înseamnă că pagina care ocupă 4096 bytes pe sistemele x86 și sisteme x64, pot salva 512 intrări în Windows 32-bit și 256 de intrări în Windows 64-bit. Executive definește numărul maxim de pagini pe care se poate aloca un număr record de descriptori prin împărțirea maximă prescrisă rigid (16777216), prin numărul de înregistrări descriptori pe pagină; pentru Windows 32-bit, numărul este 32768, și pentru Windows pe 64 de biți - 65536. Deoarece sistemul executiv utilizează prima înregistrare pe fiecare pagină pentru informațiile de identificare proprii, numărul real de descriptori disponibile la proces, ar trebui să fie obținut prin scăderea din 16777216 numărul obținut mai sus, ceea ce explică rezultatele obținute în Testlimit start: 16777216 - 65536 = 16711680 și 16777216 - 32768 = 16744488.

Versiunea pe 64 de biți de Windows la nivelul superior conține 256 de indicatori către pagina. Acest lucru înseamnă că, în general, pentru a se adapta tabelul descriptor întregul utilizează 256 MB de piscină paginată (16777216/256 * 4096). Corectitudinea acestor calcule este confirmată prin utilizarea piscina cifrele Testlimit paginată pe Windows pe 64 de biți:

Cantitatea de piscină Paged este mai mult decât suficient pentru a menține aceste structuri de date, cu toate acestea, după cum am menționat mai devreme, un proces care creează prea mulți descriptori vor rula aproape sigur din alte resurse, și în cazul în care acesta ajunge la numărul de limită descriptori pentru un singur proces atunci nu se poate deschide orice alte obiecte.

Ferestre - - - Russinovich marca în limba rusă

În mod implicit, Process Explorer arată doar descriptori care indică spre obiecte care au nume care înseamnă că nu veți vedea toate descriptorilor de proces, în cazul în care nu activați opțiunea „Show Mânerele Unnamed și mapările“ din meniul View. Iată câteva mânere anonime linie de comandă tabel descriptor:

Ferestre - - - Russinovich marca în limba rusă

Așa cum este cazul cu cele mai multe alte erori, numai codul dezvoltator, din cauza care există o scurgere, se poate repara. Dacă găsiți o scurgere într-un proces care constă din mai multe componente sau extensii, de exemplu, Explorer, Host Service sau Internet Explorer, întrebarea principală este care dintre aceste părți este responsabil pentru scurgerea. Determinarea unei astfel de componente ar permite să se evite problema prin dezactivarea sau eliminarea extensia problematică, verificați dacă există actualizări, corectarea acestei erori sau raportați-l la dezvoltator.

Din fericire, Windows include instrument de descriptori de urmărire pe care le puteți utiliza pentru a stabili faptul scurgerii și de a determina persoana responsabilă de scurgerea a software-ului. Acesta funcționează cu fiecare proces separat și este activat de sistemul de executiv pentru a înregistra activitatea stiva de fiecare dată când este creat sau închis un mâner. Puteți utiliza acest instrument sau de a folosi utilitarele Application Verifier. care poate fi descărcat gratuit de pe site-ul Microsoft, sau prin utilizarea unui program de depanare pentru Windows (Windbg). Dacă doriți ca sistemul a urmat activitatea descriptorului de proces, de la lansarea sa, va trebui să utilizați de verificare a aplicațiilor. În alte cazuri, trebuie să utilizați un debugger, și comanda! Htrace. pentru a vedea informații despre activitatea procesului.

Pentru a demonstra activitatea de urmărire în acțiune, am lansat Windbg și conectat la linia de comandă, pe care am lansat mai devreme. Pentru a activa urmărirea de descriptori, am intrat în htrace comandă cheie -enable !:

Am lăsat procesul să continue să lucreze și a schimbat din nou directorul. După aceea am trecut înapoi la Windbg, a oprit executarea procesului și a lansat htrace nici un parametru, care afișează o listă a tuturor tranzacțiilor deschise și închise care îndeplinesc procesul de termen anterior al echipei! Htrace cu parametrul instantaneu, sau de la data la care înregistrarea a fost inclusă tag-uri active. Aici sunt rezultatele comenzii pentru aceeași sesiune, debugger:

Ferestre - - - Russinovich marca în limba rusă

Dacă sunteți în căutarea doar scurgerea, atunci trebuie să utilizați! Htrace --diff cu parametru, care arată numai noi mânere de la ultima crestătură, sau de la începutul activității de cale de lansare. Așa cum era de așteptat, rezultatul rularea acestei comenzi vom vedea doar 0x22c mâner:

Ferestre - - - Russinovich marca în limba rusă

O sursă excelentă de sfaturi cu privire la modul în care se poate elimina scurgerea de descriptori este un interviu cu inginerul de suport tehnic pentru Microsoft Dzheffa Deyli (Jeff Dailey) pentru canalul 9.

Data viitoare voi revizui restricțiile stabilite pentru astfel de descriptori pe baza de resurse, cum ar fi GDI și obiecte USER. Mânerele aceste resurse sunt gestionate de subsistem Windows, care este diferit de sistemul de execuție, și, prin urmare, folosesc alte resurse și au alte limitări.