Kodėl pirmasis C++ (m) paskirstymas visada yra 72 KB?
komentarai
Mewayz Team
Editorial Team
Paslaptis už jūsų pirmojo C++ paskirstymo
Rašote paprastą C++ programą. Viena nauja int. Keturi baitai. Įjungiate strace arba mėgstamą atminties profiliavimo programą, ir viskas – jūsų procesas ką tik paprašė operacinės sistemos maždaug 72 KB. Ne 4 baitai. Ne 64 baitai. Visas 72 KB. Jei kada nors žiūrėjote į šį skaičių ir svarstėte, ar jūsų įrankiai jums meluoja, jūs nesate vieni. Šis, atrodytų, keistas elgesys yra vienas dažniausiai užduodamų klausimų tarp C++ kūrėjų, pirmą kartą besigilinančių į atminties vidines dalis, o atsakymas nuves mus į įspūdingą kelionę per sluoksnius, esančius tarp jūsų kodo ir tikrosios aparatinės įrangos.
Kas atsitinka paskambinus nauja
Norėdami suprasti 72 KB skaičių, turite atsekti visą paskirstymo grandinę. Kai jūsų C++ kodas vykdo new int, kompiliatorius tai paverčia iškvietimu operator new, kuris daugumoje Linux sistemų perduoda malloc iš glibc. Tačiau malloc tiesiogiai neprašo branduolio 4 baitų atminties. Branduolys veikia puslapiuose – paprastai 4 KB x86_64 – ir sistemos skambučio kaina yra didžiulė, palyginti su paprasta prieiga prie atminties. Iškvietus brk() arba mmap() kiekvienam atskiram paskirstymui, bet kuri nebanali programa sustotų.
Vietoj to glibc atminties skirstytuvas – įgyvendinimas, vadinamas ptmalloc2, pats kilęs iš klasikinio Dougo Lea dlmalloc, veikia kaip tarpininkas. Jis iš anksto reikalauja didelių atminties blokų iš branduolio, tada suskirsto juos į mažesnes dalis, kai jų reikia jūsų programai. Tai yra pagrindinė priežastis, dėl kurios jūsų pirmasis 4 baitų paskirstymas suaktyvina daug didesnę užklausą operacinei sistemai. Skirstytojas nesišvaisto. Tai strateginė veikla.
72 KB išskaidymas: kur eina baitai
Pradinis paskirstymas gaunamas iš kelių skirtingų komponentų, kuriuos vykdymo laikas turi inicijuoti, kad galėtų perduoti jums nors vieną baitą naudojamos atminties. Kiekvieno komponento supratimas paaiškina, kodėl skaičius patenka ten, kur jis patenka.
Pirma, glibc malloc inicijuoja pagrindinę areną – pirminę buhalterinės apskaitos struktūrą, sekančią visus paskirstymus pagrindinėje gijoje. Ši arena apima krūvos metaduomenis, laisvojo sąrašo rodykles ir skirtingų paskirstymo dydžių šiukšliadėžių struktūras. Skirstytuvas pratęsia programos pertrauką naudodamas sbrk(), o pradinį plėtinį valdo vidinis parametras, vadinamas M_TOP_PAD, kuris pagal numatytuosius nustatymus yra 128 KB užpildymo. Tačiau tikroji pradinė užklausa koreguojama atsižvelgiant į puslapio išlygiavimą ir esamą pertraukos padėtį, todėl dažnai gaunama mažesnė pirmoji užklausa – naujai pradėtame procese ji paprastai pasiekia 72 KB.
Antra, nuo glibc 2.26 versijos skirstytuvas inicijuoja vietinę gijos talpyklą (tcache) pirmą kartą naudojant. Laikinojoje atmintyje yra 64 talpyklos (viena mažo paskirstymo dydžio klasėje), kiekviena gali talpinti iki 7 talpykloje esančių dalių. Pati tcache_perthread_struct sunaudoja apie 1 KB, tačiau ją inicijuojant suaktyvinama platesnė arenos sąranka. Trečia, C++ vykdymo laikas jau atliko paskirstymus dar prieš jūsų main() paleidimą – statiniai konstruktoriai, iostream buferio inicijavimas std::cout ir draugams bei lokalės sąranka prisideda prie pradinio krūvos pėdsako.
Arenos sistema ir kodėl išankstinis paskirstymas yra protingas
Sprendimas iš anksto skirti didelę atminties dalį, o ne prašyti jos dalimis, nėra įgyvendinimo atsitiktinumas. Tai apgalvotas inžinerinis kompromisas, pagrįstas dešimtmečių sistemų programavimo patirtimi. Kiekvienas iškvietimas į brk() arba mmap() apima konteksto perjungimą iš vartotojo erdvės į branduolio erdvę, proceso virtualios atminties susiejimo modifikavimą ir galimus puslapio lentelės atnaujinimus. Šiuolaikinėje aparatinėje įrangoje vienas sistemos skambutis kainuoja maždaug 100–200 nanosekundžių – nereikšminga atskirai, katastrofiška.
Apsvarstykite programą, kuri inicijavimo metu atlieka 10 000 mažų paskirstymų. Be išankstinio paskirstymo tai reikštų 10 000 sistemos skambučių, kainuotų maždaug 1–2 milisekundes grynųjų papildomų išlaidų. Naudojant arenos skirstytuvą, pirmasis paskirstymas suaktyvina vieną sistemos iškvietimą, o paskesni 9 999 paskirstymai aptarnaujami tik vartotojo erdvėje, naudojant žymeklio aritmetines ir susieto sąrašo operacijas – kiekviena užtrunka maždaug 10–50 nanosekundžių. Matematika nedviprasmiška: išankstinis paskirstymas laimi pagal dydį.
72 KB, kuriuos matote pirmą kartą paskirstę, nėra švaistoma atmintis – tai investicija į našumą. Paskirstytojas lažinasi, kad jūsų programa netrukus skirs daugiau lėšų, ir praktiškai kiekviename realiame scenarijuje šis statymas atsiperka. Šiuolaikinėse 64 bitų sistemose nepanaudotos virtualios adresų erdvės kaina iš esmės yra lygi nuliui.
Virtuali ir fizinė atmintis: kodėl tai nesvarbu
Dažnas kūrėjų, pirmą kartą susidūrusių su tokiu elgesiu, susirūpinimas yra išteklių švaistymas. Jei man reikia tik 4 baitų, kodėl mano programa sunaudoja 72 KB? Svarbi įžvalga yra ta, kad virtualioji atmintis nėra fizinė atmintis. Kai glibc pratęsia programos pertrauką 72 KB, branduolys atnaujina proceso virtualiosios atminties atvaizdus, tačiau iš karto neatkuria tų puslapių su fizine RAM. Tikrieji fiziniai puslapiai priskiriami pagal poreikį per puslapio klaidas – tik tada, kai programa rašo konkrečiu adresu, branduolys jai priskiria tikrą atminties puslapį.
💡 DID YOU KNOW?
Mewayz replaces 8+ business tools in one platform
CRM · Invoicing · HR · Projects · Booking · eCommerce · POS · Analytics. Free forever plan available.
Start Free →Tai reiškia, kad net jei jūsų proceso virtualus dydis padidėja 72 KB, jo nuolatinio rinkinio dydis (RSS) – faktiškai sunaudojamos fizinės RAM kiekis – padidėja tik puslapiais, kuriuos iš tikrųjų paliečiate. Vienam naujam int, tai paprastai yra vienas 4 KB puslapis ir visi puslapiai, kuriuos užima arenos metaduomenys. Likusi virtuali erdvė yra paruošta naudoti ir nekainuoja nieko, išskyrus adreso erdvę, iš kurios turite 128 TB 64 bitų Linux sistemoje.
Šis skirtumas yra labai svarbus profiliuojant ir stebint gamybos programas. Jei kuriate programinę įrangą, kuriai reikia sekti tikrąjį išteklių suvartojimą – nesvarbu, ar tai būtų „SaaS“ užpakalinė programa, mikropaslaugos, ar analizės dujotiekis, pavyzdžiui, tie, kurie veikia tokiose platformose kaip Mewayz verslo operacijoms – visada turėtumėte stebėti RSS, o ne virtualų dydį. Tokie įrankiai kaip /proc/[pid]/smaps, valgrind --tool=massif ir pmap gali pateikti tikslius fizinės atminties pėdsakus, o ne klaidinančius virtualios atminties skaičius.
Kaip skirtingi skirstytojai tvarko pirmąjį paskirstymą
72 KB skaičius būdingas glibc ptmalloc2. Kiti skirstytojai daro skirtingus kompromisus, o pradinės pridėtinės išlaidos atitinkamai skiriasi. Svarbu suprasti šiuos skirtumus renkantis skirstytuvą našumui jautrioms programoms.
- jemalloc (naudojama „Facebook“, „FreeBSD“) – naudojama smulkesnė arenos struktūra su gijų vietinėmis talpyklomis. Pradinės papildomos išlaidos paprastai būna didesnės (dažnai daugiau nei 200 KB), tačiau dėl sumažėjusio užrakto našumo užtikrinamas geresnis kelių gijų našumas.
- tcmalloc („Google“ gijų talpyklos „Maloc“) – pagal numatytuosius nustatymus kiekvienai gijai priskiria maždaug 2 MB talpyklą su agresyviu išankstiniu paskirstymu. Pradinės pridėtinės išlaidos yra didesnės, bet vėlesni nedideli paskirstymai atliekami labai greitai.
- musl libc's malloc – visuose paskirstymuose naudojamas daug paprastesnis dizainas, pagrįstas mmap. Pradinės pridėtinės išlaidos yra minimalios (dažnai tik 4 KB vienam paskirstymui), tačiau paskirstymo kaina yra didesnė dėl dažnesnių sistemos skambučių.
- mimalloc („Microsoft“) – naudoja segmentais pagrįstą paskirstymą su 64 MB segmentais. Pirmasis paskirstymas suaktyvina 64 MB virtualią rezervaciją (su minimaliu fiziniu įsipareigojimu), prekybos adresų erdvę išskirtinėms vietovėms ir pralaidumui užtikrinti.
Šių skirstytuvų pasirinkimas visiškai priklauso nuo jūsų darbo krūvio. Ilgai veikiančioms serverio programoms su sunkiu kelių gijų paskirstymu jemalloc arba tcmalloc paprastai pranoksta numatytuosius glibc. Apribotos atminties įterptosiose sistemose, nepaisant mažesnio pralaidumo, geriau naudoti paprastesnį musl metodą. Daugumoje bendrosios paskirties darbalaukio ir serverio programų ptmalloc2 72 KB pradinė pridėtinė vertė yra pagrįsta numatytoji vertė, kuri gerai veikia ir be derinimo.
Pradinio paskirstymo reguliavimas
Jei numatytosios 72 KB pradinės papildomos sąnaudos yra tikrai problemiškos jūsų naudojimo atveju – galbūt sukuriate tūkstančius trumpalaikių procesų, kurių kiekvienas paskirsto tik keletą – glibc pateikia keletą derinimo priemonių per mallopt() ir MALLOC_ aplinkos kintamųjų šeimą.
Parametras M_TOP_PAD valdo, kiek papildomos atminties skirstytuvas reikalauja, nei reikia nedelsiant. Nustačius jį į 0 su mallopt(M_TOP_PAD, 0), skirstytuvui nurodoma pateikti užklausą tik tai, ko reikia, todėl pradinės papildomos išlaidos žymiai sumažėja. Parametras M_MMAP_THRESHOLD valdo dydį, kurį viršijus paskirstymas naudoja mmap, o ne areną. M_TRIM_THRESHOLD valdo, kada atlaisvinta atmintis grąžinama į OS. Ir kadangi glibc 2.26, derinimo priemonės glibc.malloc.tcache_count ir glibc.malloc.tcache_max leidžia valdyti gijų talpyklos veikimą.
Tačiau atsargumo žodis: šių parametrų derinimas be kruopštaus palyginimo beveik visada pablogina situaciją. Numatytieji nustatymai buvo pasirinkti remiantis plačiu realaus pasaulio profiliavimu, ir jie puikiai tinka daugeliui darbo krūvių. Jei neturite svarių gamybos profiliavimo įrodymų, kad malloc pridėtinės išlaidos yra kliūtis, ir įvertinote pakeitimų poveikį, palikite numatytuosius nustatymus ramybėje. Ankstyvas skirstytuvo optimizavimas yra ypač klastinga jakų skutimo forma, sunaudojusi daugybę inžinerinių valandų ir duodanti nereikšmingą naudą.
Ko tai mus moko apie sistemų programavimą
72 KB pirmojo paskirstymo paslaptis iš esmės yra pamoka apie abstrakcijos sluoksnius. C++ sukuria iliuziją, kad new int skiria 4 baitus. Kalbos standartas taip sako. Tavo psichikos modelis taip sako. Tačiau tarp jūsų kodo ir aparatinės įrangos yra daugybė sudėtingų sistemų – C++ vykdymo laikas, C bibliotekos skirstytuvas, branduolio virtualios atminties posistemis ir aparatinės įrangos MMU bei TLB – kiekviena prideda savo elgseną, optimizavimą ir pridėtines išlaidas.
Tai nėra trūkumas. Tai yra visa sistemų programinės įrangos esmė. Kiekvienas sluoksnis egzistuoja tam, kad išspręstų tikrą problemą: skirstytuvas egzistuoja, todėl jums nereikės skambinti sistemai dėl kiekvieno paskirstymo. Virtualios atminties sistema egzistuoja, todėl jums nereikia tiesiogiai valdyti fizinės atminties. Puslapio gedimų tvarkytojas egzistuoja, todėl atmintis yra naudojama tingiai ir efektyviai. Kiekvienas sluoksnis keičia nedidelį kiekį skaidrumo ir užtikrina didesnį našumą ir patogumą.
Patikimiausias ir našiausias sistemas kuria tie kūrėjai, kurie supranta šiuos sluoksnius – ne todėl, kad jiems reikia nuolat apie juos galvoti, o todėl, kad kai nutinka kažkas netikėto (pvz., paslaptingas 72 KB paskirstymas), jie turi mąstymo modelį, kad suprastų, kodėl. Nesvarbu, ar kuriate realaus laiko prekybos sistemą, žaidimų variklį ar verslo platformą, aptarnaujančią tūkstančius vartotojų, gebėjimas suprasti, ką jūsų kodas iš tikrųjų veikia sistemos lygiu, skiria kompetentingus kūrėjus nuo išskirtinių. 72 KB nėra klaida. Tai jūsų skirstytuvas puikiai atlieka savo darbą.
Sukurkite savo verslo OS šiandien
Nuo laisvai samdomų darbuotojų iki agentūrų – „Mewayz“ valdo 138 000 ir daugiau įmonių su 207 integruotais moduliais. Pradėkite nemokamai, atnaujinkite, kai augsite.
Sukurti nemokamą paskyrą →Try Mewayz Free
All-in-one platform for CRM, invoicing, projects, HR & more. No credit card required.
Get more articles like this
Weekly business tips and product updates. Free forever.
You're subscribed!
Start managing your business smarter today
Join 30,000+ businesses. Free forever plan · No credit card required.
Ready to put this into practice?
Join 30,000+ businesses using Mewayz. Free forever plan — no credit card required.
Start Free Trial →Related articles
Hacker News
Show HN: Spice simulation → oscilloscope → verification with Claude Code
Apr 17, 2026
Hacker News
Hospital at centre of child HIV outbreak caught reusing syringes in Pakistan
Apr 16, 2026
Hacker News
George Orwell Predicted the Rise of "AI Slop" in Nineteen Eighty-Four (1949)
Apr 16, 2026
Hacker News
Everything we like is a psyop
Apr 16, 2026
Hacker News
U.S. to Create High-Tech Manufacturing Zone in Philippines
Apr 16, 2026
Hacker News
New unsealed records reveal Amazon's price-fixing tactics, California AG claims
Apr 16, 2026
Ready to take action?
Start your free Mewayz trial today
All-in-one business platform. No credit card required.
Start Free →14-day free trial · No credit card · Cancel anytime