- Linux ponuja ukaze, kot so free, vmstat, ps in top, za pregled dejanske uporabe pomnilnika in procesorja, pri čemer razlikuje med uporabljenim, prostim in predpomnjenim pomnilnikom.
- Orodja, kot sta GDB in Valgrind, omogočajo zaznavanje napak segmentacije, puščanja pomnilnika, nedovoljenih dostopov in neinicializiranih spremenljivk v izvornih programih.
- V okoljih .NET Core kombinacija dotnet-dump, LLDB in SOS omogoča poglobljeno analizo izpisov pomnilnika v sistemih Linux in Windows.
- Urejen diagnostični potek dela, ki združuje sistemske metrike, dnevnike in analizo izpisa pomnilnika, drastično skrajša čas za odkrivanje in odpravljanje težav s pomnilnikom.

Ko gre na strežniku Linux kaj narobe, je vzrok pogosto v načinu uporabe pomnilnika in orodjih za odpravljanje napak , toda dokler ne veste, na kaj morate biti pozorni, se vse zdi kot kaotična zmešnjava številk in procesov. Razumevanje, kaj se dogaja v RAM-u, kako se vaši programi obnašajo in kako zajeti izpise pomnilnika, je ključnega pomena za izogibanje slepemu odpravljanju težav vsakič, ko se pojavi nenavadna napaka ali napaka segmentacije.
V tem članku si bomo podrobno in preprosto ogledali, kako pregledati pomnilnik, odpravljati napake v programih in analizirati izpise v Linuxu z uporabo sistemskih ukazov (free, vmstat, /proc/meminfo), razhroščevalnikov, kot je GDB, analizatorjev pomnilnika, kot je Valgrind, in pripomočkov, specifičnih za .NET in druga okolja. Cilj je, da si zagotovite praktičen arzenal za diagnosticiranje težav s pomnilnikom in procesorjem v strežnikih in profesionalnih razvojnih okoljih.
Pregled: Pomnilnik v Linuxu in zakaj se ne bi smeli obremenjevati s 100%
Na strežniku Linux RAM deluje kot hitro shramba za podatke in kodo, ki jih mora sistem kmalu ponovno uporabiti. Dostop do RAM-a je veliko hitrejši kot dostop do diska, zato jedro to izkoristi, da ga uporabi kot predpomnilnik za datoteke, medpomnilnike in pomnilniške strani, ki bi jih sistem morda kmalu spet potreboval.
V kontekstu spletnega strežnika, na katerem se izvaja Apache ali Nginx , ali strežnika baz podatkov, kot sta MySQL ali MariaDB, je poznavanje količine pomnilnika, ki je v uporabi, koliko je prostega in koliko je predpomnjenega, ključnega pomena za pravilno dimenzioniranje storitev in razumevanje imenskih prostorov in kontrolnih skupin . Pravzaprav orodja za optimizacijo, kot je MySQLTuner , uporabljajo te podatke (in druge informacije) za predlaganje nastavitev medpomnilnika, predpomnilnika in povezave.
Pomembno je razumeti koncept, ki ljudi sprva pogosto preseneti: RAM je zasnovan tako, da je v uporabi . 90-odstotna ali celo 100-odstotna uporaba ni nujno problem; Linux RAM zapolni s predpomnilnikom diska, da pospeši sistem. Kar je resnično zaskrbljujoče, je, ko začnete dobivati napake »pomanjkanje pomnilnika« , procesi se sesujejo s sporočilom OOM (Out Of Memory) ali storitve zamrzujejo, ne le takrat, ko graf prikazuje »visoko porabo«.
K agresivni optimizaciji je smiselno skočiti le, če opazite, da strežnik postane nestabilen, počasen ali ustavi storitve zaradi prekomerne porabe pomnilnika ali če veste, da prihajajo konice prometa, ki bi lahko preobremenile trenutne vire.
Osnovni ukazi za pregled pomnilnika v Linuxu

Prvi korak pri odpravljanju težav s pomnilnikom je razumevanje celotne količine RAM-a in kako je razdeljen med uporabljeni pomnilnik, prosti pomnilnik, predpomnilnik in swap. Linux za to ponuja več pripomočkov, vsak z drugačno stopnjo podrobnosti.
brezplačen ukaz: hiter pregled RAM-a in swap-ja
Najpogosteje uporabljen ukaz za hiter pregled je brezplačno, še posebej s parametrom -h Za prikaz velikosti v berljivi obliki: Za več informacij o interpretaciji in optimizaciji teh metrik glejte optimizirajte statistiko pomnilnika.
free -h
Tipičen izpis vam v nekaj vrsticah prikaže skupni, uporabljeni, prosti, deljeni, medpomnilniški in predpomnilniški pomnilnik , tako za RAM kot za swap prostor. Videli boste nekaj takega:
skupno uporabljeni prosti skupni predpomnilniki predpomnjeni Pomnilnik: 2.0 G 1.5 G 470 M 300 M 0 B 414 M -/+ medpomnilniki/predpomnilnik: 1.1 G 885 M Izmenjava: 0 B 0 B 0 B
Vrstica -/+ buffers/cache Še posebej uporabno je, ker prikazuje pomnilnik, ki ga dejansko uporabljajo procesi (brez medpomnilnikov/predpomnilnika), in pomnilnik, ki je potencialno na voljo za nove aplikacije. Mnogi ljudje v prvi vrstici vidijo malo "prostega pomnilnika" in se zaskrbijo, ko je v resnici velik del le predpomnjenega in ga je mogoče ponovno uporabljeno brez drame.
vmstat: metrike aktivnega, nedejavnega pomnilnika in sistema
Ko potrebujete nekaj podrobnejšega, vam vmstat ponudi bolj tehnično sliko sistema. Z:
vmstat -s -S M
Dobili boste seznam s skupnim pomnilnikom, uporabljenim pomnilnikom, prostim pomnilnikom, aktivnim pomnilnikom, neaktivnim pomnilnikom, medpomnilniki, izmenjalnim pomnilnikom itd. Na primer:
2048 M skupni pomnilnik 1582 M uporabljen pomnilnik 1124 M aktivni pomnilnik 406 M neaktivni pomnilnik 465 M prosti pomnilnik 0 M medpomnilnik 407 M predpomnilnik za izmenjavo 0 M skupna izmenjava 0 M uporabljena izmenjava 0 M prosta izmenjava
Koncept neaktivnega pomnilnika je zanimiv: to je pomnilnik, ki velja za uporabljenega, vendar ni povezan z aktivnimi procesi, zato se v praksi obnaša kot pomnilnik, ki ga lahko sistem obnovi . To pomaga razložiti, zakaj se zdi, da Linux "porablja ves prostor", v resnici pa ima prostor za sprostitev, ko je to potrebno.
/proc/meminfo: podrobnosti o surovem jedru
Če želite vse podrobnosti, ki jih jedro obravnava, si lahko vedno ogledate datoteko /proc/meminfo :
cat /proc/meminfo
Ta datoteka vsebuje na desetine polj, povezanih z upravljanjem notranjega pomnilnika : skupni pomnilnik, prosti pomnilnik, medpomnilniki, predpomnilnik, slab, ogromne strani, razpoložljivi pomnilnik itd. Zelo uporabna je za avtomatizirana orodja in skripte za spremljanje, čeprav je njeno neposredno branje nekoliko manj uporabniku prijazno kot branje `free` ali `vmstat` in zahteva temeljito razumevanje pomena posameznega polja.
Nadzorne plošče in njihova »vzporedna resničnost«
Če upravljate strežnik z nadzornimi ploščami, kot so cPanel, Plesk, VestaCP ali Webmin , boste opazili, da običajno prikazujejo grafe uporabljenega, prostega in predpomnjenega pomnilnika prek spletnega vmesnika. Ti podatki so priročni, vendar ne pozabite, da se občasno posodabljajo in včasih ne odražajo natančnega stanja v realnem času. Za temeljito diagnostiko in natančno nastavitev je vedno najbolje uporabiti terminal in njegove izvorne ukaze.
Odpravljanje napak v procesih in pomnilniku s sistemskimi orodji
Ko veste, koliko pomnilnika je na voljo in kako se na splošno uporablja, je naslednji korak iskanje procesov, ki nenormalno porabljajo vire , in analiza njihovega vedenja. Tukaj pridejo v poštev klasični pripomočki, kot so ps, top, htop, strace in ltrace, ter omrežni in diskovni ukazi, ki pomagajo odpraviti ozka grla.
ps, top in htop: rentgenski posnetek procesov in procesorja
Ukaz `ps` prikaže aktivne procese. V kombinaciji s filtri in razvrščanjem vam omogoča hitro iskanje procesov, ki porabljajo procesor.
ps aux --sort=-%cpu | head
To vam prikaže procese, razvrščene po odstotku uporabe procesorja , skupaj z porabo pomnilnika, uporabnikom in ukazom. Idealen je kot posnetek za prepoznavanje glavnega osumljenca, ko strežniku primanjkuje virov; obvladovanje terminala vam pomaga hitro ukrepati.
Po drugi strani pa `top` in njegova bolj vizualna različica `htop` ponujata pogled v realnem času na procese, porabo procesorja, porabo pomnilnika, stanje (R, S, D itd.) in povprečno obremenitev . `top` začnemo z:
top -o %CPU
Osredotočite se lahko na to, kateri procesi največ uporabljajo procesor. Poleg številk je pomembno iskati tudi vzorce :
- Procesi v stanju R (izvaja se) ki dolgo časa ostanejo na vrhu.
- Nenadne spremembe povprečne obremenitve ki kažejo na nedavne poraste obremenitve.
- Dodelitev CPU-ja v %us, %sy in %wa (uporabniški čas, sistemski čas in čakanje na V/I).
- Če je problematičen postopek sistemska storitev, določen uporabnik ali demon.
- Če je poraba stabilna oz. Sunkovito se premika gor in dol., kar lahko kaže na paketna opravila ali nepravilen promet.
Zelo visoka vrednost %wa (čakanja na V/I) kaže, da ozko grlo morda ni v procesorju, temveč v disku ali podsistemu za shranjevanje.
Pregledovanje niti procesa: top -H
Pri večnitnih aplikacijah (Java, Python, Node itd.) ni dovolj vedeti, kateri proces porablja procesor; videti morate, katera specifična nit je izven nadzora . Z:
top -H -p PID
Podrobnosti o vsaki niti znotraj procesa dobite. Če se ena od njih prikaže s 100 % obremenitvijo, ostale pa so nedejavne, je verjetno v tem delu kode prisotna neskončna zanka, nenavadna težava z blokiranjem ali slabo zasnovan kritični del .
Prioriteta procesa: lepo in lepo
Če je proces, ki porablja veliko virov, legitimen, vendar želite preprečiti, da bi preobremenil preostali del sistema, lahko prilagodite njegovo prioriteto (prijaznost) . Ukaza `nice` in `renice` vam omogočata zagon procesov z nižjo prioriteto ali prilagoditev prioritete obstoječega procesa, tako da jim jedro dodeli manj procesorskega časa v primerjavi z drugimi kritičnimi nalogami.
Drugi ključni ukazi: pidof, kill, strace in ltrace
Ko je sistem pod pritiskom, je koristno, da lahko hitro lociramo in nadzorujemo procese:
- pidof: pridobi PID procesa iz njegovega imena, kar je idealno za skripte ali hitre intervencije.
- ubiti: pošilja signale procesom (TERM, KILL itd.), bodisi za urejeno zaustavitev bodisi za prekinitev opravila, če so se zataknili.
- strace: prikazuje sistemski klici ki izvaja proces; idealno za ogled tega, na čem je obtičal (branje diska, vtičnice itd.).
- ltracePodobno kot strace, vendar osredotočeno na klici v knjigarne, uporabno za odpravljanje težav z uporabo skupnega API-ja.
Ta orodja niso uporabna le za iskanje puščanja pomnilnika ali zrušitev, temveč se pogosto uporabljajo tudi v kibernetski varnosti, forenzični analizi in odpravljanju napak zaradi nenavadnega vedenja binarnih datotek .
Ukazi za datoteke in disk: lsof, df, du, locate
Ko sumite, da je s pomnilnikom nekaj narobe (na primer, veliko odprtih datotek ali polni diski), pridejo v poštev drugi ukazi:
- tudi: naštej datoteke, ki jih odpre proces, uporabno za iskanje puščanj deskriptorjev ali datotek, ki preprečujejo odklop datotečnega sistema.
- df: prikazuje prost prostor na disku po datotečnem sistemu, kar je bistveno za izključitev 100 % diskov, ki povzročajo kaskadne napake.
- duizračunaj prostor, ki ga uporabljajo imeniki, zelo uporabno za iskanje map, ki nenadzorovano rastejo (dnevniki, varnostne kopije itd.).
- poiščite: omogoča iskanje datoteke po imenu z uporabo indeksirane baze podatkov, kar je v mnogih primerih hitreje kot iskanje.
Omrežni ukazi za diagnostiko: nc, netstat, ab, tcpdump, wireshark, nmap
Težave z zmogljivostjo in pomnilnikom pogosto spremljajo ozka grla v omrežju ali napadi , zato je dobro imeti pri roki nekaj osnovnih orodij:
- nc (netcat): pravi švicarski nož za mreženje; odpira vtičnice, pošilja in prejema podatke, omogoča testiranje storitev, celo improvizirane predore.
- NetStat: prikazuje aktivne povezave, poslušalne vtičnice in statistiko omrežja, kar je uporabno za preverjanje, ali je na določena vrata veliko povezav.
- ab (Apachejeva primerjalna vrednost): ustvari obremenitev spletnega strežnika za merjenje odzivnih časov in vedenja pod obremenitvijo.
- tcpdump in WiresharkZajamejo omrežne pakete, da poglobljeno analizirati promet; tcpdump v konzoli, Wireshark z grafičnim vmesnikom.
- nmapSkener vrat in storitev, ki se pogosto uporablja tako za varnostne preglede kot za preverjanje površina izpostavljenosti strežnika.
GDB: klasični razhroščevalnik za napake pomnilnika in zrušitve med izvajanjem
Ko se program v Linuxu sesuje zaradi napake segmentacije ali druge večje napake, je naslednji logičen korak uporaba dobrega razhroščevalnika. Zvezdniško orodje v svetu GNU je GDB (GNU Debugger) , ki vam omogoča pregled notranjega stanja programa, njegovo zaustavitev kjer koli želite, ogled spremenljivk in porabe pomnilnika ter sledenje izvajanju korak za korakom.
GDB je bil prvotno zasnovan za programe C in C++, vendar je bil razširjen tudi na druge jezike, kot sta Rust in celo Assembly , ter na obravnavo poti knjižnic, kot je LD_LIBRARY_PATH . Je temeljnega pomena ne le pri razvoju, ampak tudi pri kibernetski varnosti, kjer se uporablja za obratni inženiring, iskanje ranljivosti ter razvoj ali odpravljanje napak pri izkoriščanju ranljivosti.
Zaženite GDB in zaženite program
Za uporabo GDB z izvedljivo datoteko je priporočljivo, da program prevedete z informacije o odpravljanju napak z uporabo možnosti -g iz GCC-ja:
gcc -g -Wall programa.c -o programa
Nato ga zaženete z:
gdb programa
Znotraj GDB-ja se program še ne izvaja. Zaženete ga lahko z:
- runZaženite program s poljubnimi argumenti.
- Začetek: enako kot run, vendar se ustavi na začetku funkcije
main.
Če imate izvedljivo datoteko z imenom, na primer suma In če želite videti, kako obdeluje svoje argumente, bi šli v GDB in nato uporabili run 3 5 da ga zaženete s temi parametri iz razhroščevalnika.
Prekinitvene točke in nadzorne točke: zaustavitev programa, kjer je to potrebno
Prekinitvene točke so točke zaustavitve v izvorni kodi: ko jih izvajanje doseže, se program ustavi in lahko si ogledate njegovo notranje stanje. V GDB so definirane z ukazom :
break lugar
kjer je »lokacija« lahko ime funkcije, številka vrstice ali datoteka:vrstica . Tipičen primer bi bil:
break main
tako da se GDB ustavi takoj, ko vstopi v glavno funkcijo. Ko se program ustavi na prelomni točki, si lahko kodo ogledate z l (seznam), preverite spremenljivke in se pomikate po skladu klicev.
Nadzorne točke delujejo drugače: namesto da se ustavijo na določeni točki v kodi, se ustavijo, ko se vrednost spremenljivke spremeni . Zelo uporabne so za zaznavanje poškodb pomnilnika ali nepričakovanih sprememb kritičnih struktur, ne da bi bilo treba kodo preobremeniti s stavki za tiskanje.
Fina kontrola pretoka: korak, naslednji, nadaljevanje, zaključek
Ko je program ustavljen na prelomni točki, imate na voljo več načinov za nadaljevanje:
- korak: izvede naslednjo vrstico in vstopi v klicane funkcije.
- Naslednja: izvede naslednjo vrstico brez vnosa funkcij (izvede jih "vse naenkrat").
- naprej: nadaljuje izvajanje do naslednje prekinitvene točke ali dokler se program ne zaključi.
- konča: nadaljuje, dokler se trenutna funkcija ne vrne in se vrne na točko, od koder je bila poklicana.
To vam omogoča, da sumljivo kodo pregledate korak za korakom, ne da bi morali "pogoltniti" celoten program. Priročen trik: v GDB, S pritiskom na tipko Enter ponovite zadnji ukazidealno za izdelavo mnogih next o step sledi manj tipkanja.
Sklad klicev in okvirji: poglejte, kako smo prišli do sem
Da bi razumeli, zakaj je na določeni točki prišlo do napake, je ključnega pomena videti, katere funkcije so bile poklicane pred to točko. Struktura, ki shranjuje te informacije, je klicni sklad . GDB ponuja več ukazov za njegovo upravljanje:
- bt (povratna sled): prikaže celoten sklad s seznamom ugnezdenih funkcij in številkami okvirjev.
- up: premakne se za eno raven navzgor v skladu, do točke, ki je poklicala trenutno funkcijo.
- navzdol: gre za eno raven nižje, do funkcije, ki se je izvajala.
- fr (okvir): prikaže trenutni okvir ali vam omogoča preklop na drugega z navedbo njegove številke.
To vam omogoča, da se pozicionirate na različnih ravneh klica (na primer, da skočite iz notranje funkcije v funkcijo main ) in si ogledate, kako so bile spremenljivke na posameznih mestih.
Interakcija s pomnilnikom: nastavitev, vrnitev, povratna sled yx
Ena od velikih prednosti GDB je, da omogoča branje in spreminjanje pomnilnika, medtem ko je program ustavljen. Nekatere uporabne operacije vključujejo:
- nastavite: spremeni vrednost spremenljivke med izvajanjem, idealno za testiranje scenarijev brez ponovnega prevajanja.
- vrnjena vrednost: prisili trenutno funkcijo, da vrne določeno vrednost, ne da bi nadaljevala z izvajanjem svoje kode.
- povratna sled: že videno, za prikaz trenutnega sklada klicev.
- x: pregleda vsebino pomnilnika, začenši z naslovom, z različnimi formati in velikostmi (na primer
x/4xw 0x7fffffffe000za ogled štirih besed v šestnajstiškem zapisu).
S temi možnostmi lahko replicirate napake, preverite, ali nevaren vhod povzroči prelivanje, ali pregledate kompleksne podatkovne strukture na skladu ali kopici.
Odpravljanje napak po smrti z izpisi osnovnih podatkov
Linux lahko ustvari osnovno datoteko , ko se proces sesuje zaradi signala, kot je SIGSEGV. Ta datoteka vsebuje celotno stanje procesa v času sesutja: pomnilnik, registre, sklad itd. Če jo želite aktivirati v seji, preprosto:
ulimit -c unlimited
Če jih želite trajno omogočiti za uporabnike, lahko uredite datoteko /etc/security/limits.conf in dodate vrstico, kot je ta:
* soft core unlimited
Ko se program sesuje, v delovnem imeniku ustvari datoteko, ki se običajno imenuje »core« . Nato jo lahko analizirate z GDB takole:
gdb ejecutable core
To vam omogoča, da izvedete analizo po zasnovi skoraj tako, kot da bi bil program še aktiven, kar je idealno, kadar napake ni mogoče enostavno ponovljivo odpraviti na zahtevo.
Valgrind: iskanje puščanj pomnilnika in napak
Za številne težave s pomnilnikom v C/C++ (in podobnih jezikih) GDB ni zadosten, ker ni zasnovan za samodejno zaznavanje nedovoljenih branj, puščanj ali neinicializirane uporabe pomnilnika . Tukaj pride na vrsto Valgrind – sistem za odpravljanje napak in profiliranje, ki emulira procesor in spremlja vsak dostop do pomnilnika.
Valgrind vključuje več orodij, najpogosteje pa je uporabljeno Memcheck , ki nadomešča standardni upravljalnik pomnilnika v jeziku C s svojim lastnim, ki ima zaščitne cone okoli dodeljenih blokov . To mu omogoča zaznavanje:
- Neinicializirana poraba pomnilnika (spremenljivke, ki se uporabijo, preden jim dodelimo vrednost).
- Branja/pisanja po opravljanju prostega dela (uporaba po sprostitvi).
- Dostop zunaj meja bloka pomnilnika.
- Puščanje pomnilnika (malloc brez prostega, izgubljeni kazalci itd.).
Primer brez napak: »čist« program v programu Memcheck
Recimo, da prevedete majhen program "hello world" z informacijami za odpravljanje napak:
gcc -Wall -gstabs valgrind_hello_good.c -o valgrind_hello_good
Če ga zaženete pod Valgrindom z:
valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_good
Pridobili boste sled, kjer na koncu POVZETEK NAPAK kaže 0 napak in ni poročanih o puščanju. To potrjuje, da program, vsaj z vidika Memchecka, ne kaže anomalij pomnilnika.
Zaznavanje puščanja pomnilnika
Če spremenite kodo tako, da izvede malloc brez sprostitve (na primer tako, da rezervirate bajt in ga nikoli ne sprostite) in jo ponovno prevedete:
gcc -Wall -gstabs valgrind_hello_bad.c -o valgrind_hello_bad
pri teku:
valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_bad
Valgrind bo prikazal povzetek pomnilnika HEAP z vrednostjo »v uporabi ob izhodu«, ki ni enaka nič, kar označuje količino nesproščenega pomnilnika. Poleg tega bo razdelek »dokončno izgubljen« prikazal število uhajajočih bajtov in blokov, skupaj s sledjo klica, ki je povzročil uhajanje (funkcija, datoteka in vrstica kode).
Za bolj zapletene primere, kjer se uporabljajo filtri, npr. 100 bajtov v funkciji leak()Izhod iz Valgrinda vas bo jasno usmeril k malloc problematično, kar omogoča dodajanje free ustrezno in nato preverite, ali se povzetek vrne na ničelna puščanja.
Nezakonita dejanja in dostop izven dosega
Druga tipična napaka, ki jo zazna Memcheck, je pisanje na neveljavne naslove , na primer pisanje na pomnilniško lokacijo 0 (NULL) ali onkraj konca polja. Če prevedete program, ki izvede neveljavno pisanje:
gcc -gstabs -Wall valgrind_illegal_read_write.c -o valgrind_illegal_read_write
in ga zaženete z:
valgrind -v ./valgrind_illegal_read_write
Videli boste sporočila, kot so:
Neveljaven zapis velikosti 4 pri 0x80483C4: glavni naslov (valgrind_illegal_read_write.c:8) ni skladan, mallociran ali (nedavno) prost.
To vam pove natančno, kje je prišlo do nezakonitega pisanja in kako veliko je bilo, kar se pri običajnih izvedbah običajno pokaže kot preprosta "napaka segmentacije" brez nadaljnjih namigov.
Neinicializirane spremenljivke in njihove odvisnosti od vrednosti
Memcheck vas opozori tudi, ko Odločitev o krmiljenju je odvisna od neinicializirane spremenljivkeČe prevedete program z lokalno spremenljivko, ki ni nikoli inicializirana in se uporablja v if:
gcc -gstabs -Wall valgrind_unitialized.c -o valgrind_unitialized
in ga zaženete z:
valgrind -v --track-origins=yes ./valgrind_unitialized
Izhod bo vseboval nekaj takega:
Pogojni skok ali premik je odvisen od neinicializiranih vrednosti pri 0x80483F2: main (valgrind_unitialized.c:9). Neinicializirana vrednost je bila ustvarjena z dodelitvijo sklada pri 0x80483EA: main (valgrind_unitialized.c:7).
Parameter –track-origins=yes pomaga najti, kje je bila neinicializirana spremenljivka prvič ustvarjena, kar močno pospeši popravljanje kode.
Zloraba prostega in zaznavanja napak v kopici
Valgrind to tudi potrjuje Funkcija free se pokliče samo pri veljavnih kazalcih.Če poskušate sprostiti pomnilnik, ki ne prihaja iz mallocAli če dvakrat kliknete na isti blok, boste prejeli sporočila, kot je to:
Neveljavna funkcija free() / delete / delete[] / realloc() pri 0x402B06C: free (...) od 0x8048449: main (valgrind_illegal_free.c:11)
V mnogih primerih vam celo pove, da je naslov, s katerega kličete free Nahaja se takoj za blokom, ki je že bil sproščen, kar omogoča identifikacijo napake pri izračunu kazalca ali dvojne sprostitve.
Skratka, Valgrind je bistveno orodje, kadar sumite na puščanje pomnilnika, uporabo po sprostitvi ali poškodbo pomnilnika v izvornih programih, njegova kombinirana uporaba z GDB pa zagotavlja zelo močan vpogled v notranje stanje aplikacij.
Izpisi in analiza osnovnih podatkov v Linuxu in Windowsu
V sodobnih aplikacijah, zlasti v .NET Core , analiziranje kompleksnih težav s pomnilnikom ali zmogljivostjo pogosto vključuje zajemanje izpisov pomnilnika za natančno analizo na drugem računalniku. Ti izpisi zamrznejo stanje procesa na določeni točki v času, tako kot tradicionalni izpisi jedra.
Analiza izpisov .NET v Linuxu z dotnet-dump in LLDB
V okoljih .NET Core v sistemu Linux je eno od priporočenih orodij dotnet-dump . Ko zajamete izpis pomnilnika, lahko analizo začnete z:
dotnet-dump analyze <dump-file>
Pomembno je, da se analiza izvede na računalniku z enako arhitekturo in distribucijo Linuxa kot okolje, v katerem je bil ustvarjen izpis podatkov. dotnet-dump je namenjen upravljani kodi .NET; za analizo izvorne kode (C/C++) je primerneje uporabiti LLDB skupaj z razširitvijo SOS.
LLDB omogoča odpravljanje napak tako v upravljani kot v izvorni kodi, s pomočjo dotnet-sos pa lahko namestite razširitev SOS, ki ponuja posebne ukaze za .NET. Za pravilno nalaganje izpisa pomnilnika .NET Core LLDB in SOS zahtevata določene binarne datoteke iz okolja, kjer je bil izpis ustvarjen:
- libmscordaccore.so
- libcoreclr.so
- dotnet (gostitelj, ki se uporablja za zagon aplikacije)
Te binarne datoteke je običajno mogoče prenesti z orodjem dotnet-symbol . Če gre za zasebno gradnjo ali če niso na strežniku simbolov, jih lahko vedno kopirate z izvirnega računalnika. Če binarne datoteke niso vključene v datoteko za izpis pomnilnika, lahko v LLDB/SOS uporabite naslednje:
setclrpath <ruta>da označite, kje se nahajajo binarne datoteke .NET Core.setsymbolserver -directory <ruta>za določitev lokacije simbolov.
Ko imate vse, kar potrebujete, naložite izpis v LLDB in kot izvedljivo datoteko za odpravljanje napak navedite gostitelja dotnet:
lldb --core <dump-file> <host-program>
tukaj To je pot do odlagališča in Običajno je binaren. dotnet, razen če gre za samostojno aplikacijo, v tem primeru bi bila to lastna izvedljiva datoteka aplikacije (brez pripone .dll).
Znotraj LLDB je pogosto treba konfigurirati pravilen strežnik simbolov z setsymbolserver -ms za uporabo Microsoftovega strežnika ali setsymbolserver -directory <ruta> za lokalni imenik in zaženite loadsymbols za nalaganje izvornih simbolov. Od tam lahko uporabite običajne ukaze SOS za analizo upravljane kopice, niti, izjem itd.
Analiza izpisa podatkov iz sistema Windows za Linux
Izpisi podatkov, ustvarjeni v Linuxu, niso omejeni na analizo v istem sistemu; odpreti jih je mogoče tudi iz sistema Windows z orodji, kot so Visual Studio, WinDbg ali dotnet-dump. Zmogljivosti se razlikujejo:
- Visual Studio: omogoča čiščenje odlagališč z mešanico izvorna in upravljana kodaz zelo uporabniku prijaznim grafičnim vmesnikom. Priporočljivo je, da si ogledate poseben priročnik za Odpravljanje napak v izpisih pomnilnika Visual Studia.
- windbgNapredna podpora za uporabniške izpise, vključno z Izpisi Linuxa z delovnim potekom, podobnim tistemu v sistemu Windows. Za izpise iz okolij Linux x64 ali Arm64 morate uporabiti različico WinDbg x64, za izpise x86 pa različico x86.
- dotnet-dump V sistemu Windows: uporablja se na enak način kot v Linuxu, z
dotnet-dump analyzeNe pozabite izbrati različice orodja x64 ali x86 glede na arhitekturo izpisa.
Profesionalna diagnoza visoke porabe procesorja in pomnilnika
Poleg specifičnih orodij čiščenje pomnilnika v Linuxu običajno vključuje strukturiran potek dela , da se izognemo naključnim dejanjem. Praktična shema za strežnike je naslednja:
- Poglej vrh za odkrivanje sumljivih vzorcev in postopkov nalaganja.
- Potrdi s ps procesi, ki porabijo največ procesorja in pomnilnika.
- Preverite, ali je poraba logična (prevajanja, paketna obdelava, indeksiranje) ali pa diši po anomalnem vedenju.
- Analizirajte niti z zgornji -H -p PID ko gre za večnitne procese.
- Za pregled dnevniki storitev z journalctl ali repom.
- Preverite, ali je težava res povezana s procesorjem ali skrita v ... V/I diska z uporabo iostata.
Za ugotavljanje, ali je ozko grlo v procesorju ali disku, je zelo koristen ukaz iostat -xz 1 3 : če vidite diske z visoko izkoriščenostjo in dolgimi čakalnimi časi, skupaj z visokim %wa v top , težava verjetno ni v procesorju, temveč v pomnilniku.
Z uporabo tega poteka dela je lažje diagnosticirati primere, kot so:
- Boti ali zlonamerni promet sprožanje procesov php-fpm in preobremenitev spletnega strežnika.
- Un Mikroservis Java z nitjo v neskončni zanki porabijo celotno jedro.
- Python proces, ki je videti vezan na procesor, vendar je v resnici zaklenjeno čaka na disk v vsaki iteraciji zanke.
Z združevanjem sistemskih orodij (ps, top, vmstat, free), razhroščevalnikov (GDB, LLDB, dotnet-dump), analizatorjev pomnilnika (Valgrind) ter omrežnih in diskovnih ukazov lahko ustvarite način dela, kjer težave s pomnilnikom in zmogljivostjo v Linuxu prenehajo biti črna skrinjica in postanejo nekaj, kar je z metodo in potrpežljivostjo mogoče prepoznati in odpraviti s precejšnjo natančnostjo.