Miksi ensimmäinen C++ (m)-varaus on aina 72 kt?
Kommentit
Mewayz Team
Editorial Team
Ensimmäisen C++-varauksesi mysteeri
Kirjoitat yksinkertaisen C++-ohjelman. Yksittäinen uusi int. Neljä tavua. Käynnistät stracen tai suosikkimuistiprofiilisi, ja siinä se on – prosessisi pyysi juuri noin 72 kt käyttöjärjestelmältä. Ei 4 tavua. Ei 64 tavua. Täysi 72 kt. Jos olet joskus tuijottanut tuota numeroa ja miettinyt, valehtelivatko työkalusi sinulle, et ole yksin. Tämä näennäisesti oudolta vaikuttava toiminta on yksi useimmin kysytyistä kysymyksistä C++-kehittäjien keskuudessa, jotka tutkivat muistin sisäisiä osia ensimmäistä kertaa, ja vastaus vie meidät kiehtovalle matkalle koodisi ja varsinaisen laitteiston välissä olevien kerrosten läpi.
Mitä tapahtuu, kun soitat uudelle
Jotta ymmärrät 72 kt:n luvun, sinun on jäljitettävä koko allokointiketju. Kun C++-koodisi suorittaa new int, kääntäjä muuttaa sen kutsuksi operaattori new, joka useimmissa Linux-järjestelmissä siirtää mallocin glibc:stä. Mutta malloc ei kysy suoraan ytimältä 4 tavua muistia. Ydin toimii sivuilla – tyypillisesti 4 kt x86_64:llä – ja järjestelmäkutsun hinta on valtava verrattuna yksinkertaiseen muistin käyttöön. brk()- tai mmap()-kutsu jokaiselle yksittäiselle allokoinnille saattaisi kaikki ei-triviaalit ohjelmat pysähtymään.
Sen sijaan glibc:n muistinvaraaja – toteutus nimeltä ptmalloc2, joka itse on peräisin Doug Lean klassisesta dlmallocista – toimii välittäjänä. Se pyytää suuria muistilohkoja ytimeltä etukäteen ja leikkaa ne sitten pienemmiksi paloiksi, kun ohjelmasi niitä tarvitsee. Tämä on perussyy, miksi ensimmäinen 4-tavuinen varaus laukaisee paljon suuremman pyynnön käyttöjärjestelmälle. Alokaattori ei ole tuhlaava. Se on strategista.
72 kt:n erittely: minne tavut menevät
Alkuvarauskustannukset tulevat useista erillisistä komponenteista, jotka suoritusajan on alustettava, ennen kuin se voi antaa sinulle edes yhden tavun käyttökelpoista muistia. Kunkin komponentin ymmärtäminen selittää, miksi numero osuu sinne, missä se osuu.
Ensin glibc:n malloc alustaa pääareenan – ensisijaisen kirjanpitorakenteen, joka seuraa kaikkia pääsäikeen varauksia. Tämä areena sisältää keon metatiedot, vapaan listan osoittimia ja bin rakenteita eri allokointikokoja varten. Kohdistus pidentää ohjelman kestoa sbrk()-komennolla, ja alkuperäistä laajennusta ohjaa sisäinen parametri nimeltä M_TOP_PAD, jonka oletusarvo on 128 kt täyte. Varsinaista alkuperäistä pyyntöä kuitenkin mukautetaan sivun tasauksen ja olemassa olevan katkon sijainnin mukaan, mikä johtaa usein pienempään ensimmäiseen pyyntöön – yleensä lähellä 72 kt:n lukua juuri aloitetussa prosessissa.
Toiseksi glibc 2.26:n jälkeen allokaattori alustaa säikeen paikallisen välimuistin (tcache) ensimmäisellä käyttökerralla. Tcache sisältää 64 laatikkoa (yksi pientä kohdetta kohden), joista kuhunkin mahtuu jopa 7 välimuistissa olevaa palaa. Itse tcache_perthread_struct kuluttaa noin 1 kt, mutta sen alustus käynnistää laajemman areenan asennuksen. Kolmanneksi C++-suoritusaika on jo suorittanut varauksia ennen kuin main() edes suoritetaan – staattiset konstruktorit, iostream-puskurin alustus std::cout- ja ystäville sekä maa-asetusten määrittäminen vaikuttavat tähän alkuperäiseen kasaan.
Arenajärjestelmä ja miksi ennakkovaraus on järkevää
Päätös varata etukäteen huomattava osa muistista sen sijaan, että sitä pyydettäisiin osittaisesti, ei ole toteutus sattuma. Se on tietoinen tekninen kompromissi, jonka juuret ovat vuosikymmenten järjestelmäohjelmointikokemus. Jokainen brk()- tai mmap()-kutsu sisältää kontekstin vaihdon käyttäjätilasta ydintilaan, prosessin virtuaalisen muistin määritysten muokkaamisen ja mahdollisia sivutaulukkopäivityksiä. Nykyaikaisella laitteistolla yksi järjestelmäpuhelu maksaa noin 100–200 nanosekuntia – yksittäin triviaali, mittakaavassa katastrofaalinen.
Ajattele ohjelmaa, joka tekee 10 000 pientä varausta alustuksen aikana. Ilman ennakkovarausta se merkitsisi 10 000 järjestelmäpuhelua, jotka maksaisivat noin 1-2 millisekuntia puhdasta yleiskustannuksia. Areenapohjaisessa allokaattorissa ensimmäinen allokointi laukaisee yhden järjestelmäkutsun, ja seuraavat 9 999 allokaatiota palvellaan kokonaan käyttäjätilassa osoitinaritmeettisten ja linkitettyjen listatoimintojen avulla – kukin vie noin 10-50 nanosekuntia. Matematiikka on yksiselitteinen: ennakkovaraus voittaa suuruusluokkaa.
Ensimmäisellä varauksella näkemäsi 72 kt ei ole hukkaan heitettyä muistia – se on suorituskykyinvestointi. Alokaattori lyö vetoa, että ohjelmasi tekee lisää allokaatioita pian, ja käytännössä kaikissa tosielämän skenaarioissa tämä veto maksaa komeasti. Käyttämättömän virtuaalisen osoitetilan hinta on käytännössä nolla nykyaikaisissa 64-bittisissä järjestelmissä.
Virtuaalinen muisti vs. fyysinen muisti: miksi sillä ei ole väliä
Yleinen huolenaihe kehittäjien keskuudessa, jotka kohtaavat tällaisen toiminnan ensimmäistä kertaa, on resurssien tuhlaus. Jos tarvitsen vain 4 tavua, miksi ohjelmani kuluttaa 72 kt? Kriittinen näkemys on, että virtuaalimuisti ei ole fyysistä muistia. Kun glibc pidentää ohjelmakatkoa 72 kilotavulla, ydin päivittää prosessin näennäismuistin kartoituksia, mutta se ei välittömästi palauta näitä sivuja fyysisellä RAM-muistilla. Varsinaiset fyysiset sivut jaetaan pyynnöstä sivuvirheiden kautta – vain kun ohjelma kirjoittaa tiettyyn osoitteeseen, ydin osoittaa sille todellisen muistisivun.
💡 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 →Tämä tarkoittaa, että vaikka prosessisi virtuaalinen koko kasvaa 72 kt, sen resident set size (RSS) eli tosiasiallisesti kulutetun fyysisen RAM-muistin määrä kasvaa vain niillä sivuilla, joita todella kosketat. Yhdelle uudelle int:lle se on yleensä yksi 4 kt:n sivu sekä kaikki sivut, joita areenan metatiedot vievät. Jäljelle jäävä virtuaalitila on valmiina käyttöön, ja se ei maksa muuta kuin osoitetilaa – josta sinulla on 128 Tt 64-bittisessä Linux-järjestelmässä.
Tämä ero on kriittinen tuotantosovelluksia profiloitaessa ja valvottaessa. Jos rakennat ohjelmistoja, joiden on seurattava todellista resurssien kulutusta – olipa kyseessä SaaS-taustajärjestelmä, mikropalvelu tai analytiikkaputki, kuten ne, jotka toimivat alustoilla, kuten Mewayz liiketoimintaa varten – sinun tulee aina seurata RSS-syötteitä virtuaalisen koon sijaan. Työkalut, kuten /proc/[pid]/smaps, valgrind --tool=massif ja pmap, voivat antaa sinulle tarkkoja fyysisiä muistijalanjälkiä harhaanjohtavien virtuaalimuistilukujen sijaan.
Miten eri allokaattorit käsittelevät ensimmäistä varausta
72 kt:n luku koskee glibc:n ptmalloc2:ta. Muut allokaattorit tekevät erilaisia kompromisseja, ja alkuperäinen allokoinnin yleiskustannukset vaihtelevat vastaavasti. Näiden erojen ymmärtäminen on hyödyllistä valittaessa allokaattoria suorituskykyherkille sovelluksille.
- jemalloc (käyttää Facebookissa, FreeBSD:ssä) – Käyttää tarkempaa areenarakennetta säikeen paikallisten välimuistien kanssa. Alkuperäinen lisäkustannus on yleensä suurempi (usein yli 200 kt), mutta se tarjoaa paremman monisäikeisen suorituskyvyn vähentyneen lukkokiistan ansiosta.
- tcmalloc (Googlen Thread-Caching Malloc) – Varaa säiettä kohden noin 2 Mt:n välimuistin oletuksena aggressiivisella esivarauksella. Alkuperäiset yleiskustannukset ovat korkeammat, mutta seuraavat pienet allokaatiot ovat erittäin nopeita.
- musl libc:n malloc – käyttää paljon yksinkertaisempaa mmap-pohjaista suunnittelua kaikissa allokaatioissa. Alkuperäiset lisäkustannukset ovat minimaaliset (usein vain 4 kt per allokaatio), mutta allokaatiokohtainen hinta on korkeampi, koska järjestelmäkutsut tulevat useammin.
- mimalloc (Microsoft) – Käyttää segmenttipohjaista varausta 64 Mt:n segmenteillä. Ensimmäinen varaus laukaisee 64 Mt:n virtuaalisen varauksen (minimaalisella fyysisellä sitoutumisella), kaupankäyntiosoitetilan poikkeuksellisen sijainnin ja suorituskyvyn takaamiseksi.
Valinta näiden allokaattoreiden välillä riippuu täysin työmäärästäsi. Pitkäkestoisissa palvelinsovelluksissa, joissa on raskas monisäikeinen varaus, jemalloc tai tcmalloc ylittää tyypillisesti glibc:n oletusarvot. Muistirajoitetuissa sulautetuissa järjestelmissä muslin yksinkertaisempi lähestymistapa saattaa olla parempi alhaisemmasta suorituskyvystä huolimatta. Useimmille yleiskäyttöisille työpöytä- ja palvelinsovelluksille ptmalloc2:n 72 kt:n alkurasi on kohtuullinen oletusarvo, joka toimii hyvin ilman viritystä.
Alkuperäisen kohdistamiskäyttäytymisen säätäminen
Jos oletusarvoinen 72 kt:n alkuraja on aidosti ongelmallinen käyttötapauksessasi – ehkä synnytät tuhansia lyhytikäisiä prosesseja, joista kukin tekee vain kourallisen varauksia – glibc tarjoaa useita virityksiä mallopt()- ja MALLOC_-ympäristömuuttujien perheen
kautta.Parametri M_TOP_PAD ohjaa, kuinka paljon lisämuistia allokaattori pyytää välittömästi tarvittavan määrän lisäksi. Jos arvoksi asetetaan 0 komennolla mallopt(M_TOP_PAD, 0), allokaattori pyytää vain sitä, mikä on tarpeen, mikä vähentää merkittävästi alkukustannuksia. Parametri M_MMAP_THRESHOLD ohjaa kokoa, jonka yläpuolella allokoinnit käyttävät mmapa areenan sijaan. M_TRIM_THRESHOLD ohjaa, milloin vapautunut muisti palautetaan käyttöjärjestelmään. Ja glibc 2.26:n jälkeen glibc.malloc.tcache_count- ja glibc.malloc.tcache_max-viritykset antavat sinun hallita säikeen välimuistin toimintaa.
Varoituksen sana kuitenkin: näiden parametrien säätäminen ilman huolellista vertailua pahentaa lähes aina tilannetta. Oletusasetukset valittiin laajan reaalimaailman profiloinnin perusteella, ja ne ovat hyvä paikka suurimmalle osalle työkuormista. Ellei sinulla ole vahvaa näyttöä tuotannon profiloinnista siitä, että malloc overhead on pullonkaula – ja olet mitannut muutosten vaikutuksen – jätä oletusasetukset rauhaan. Alokaattorin ennenaikainen optimointi on erityisen salakavala jakin parranajon muoto, joka on kuluttanut lukemattomia suunnittelutunteja ja josta on mitätöntä hyötyä.
Mitä tämä opettaa meille järjestelmäohjelmoinnista
72 kt:n ensisijainen mysteeri on pohjimmiltaan oppitunti abstraktiotasoista. C++ antaa sinulle illuusion, että new int varaa 4 tavua. Kielistandardi sanoo niin. Henkinen mallisi sanoo niin. Mutta koodisi ja laitteistosi välissä on pino kehittyneitä järjestelmiä – C++-ajoaika, C-kirjaston allokaattori, ytimen virtuaalimuistin alijärjestelmä sekä laitteiston MMU ja TLB – jotka kukin lisäävät omat käyttäytymisensä, optimointinsa ja lisäkustannuksiaan.
Tämä ei ole virhe. Se on koko järjestelmäohjelmiston ydin. Jokainen kerros on olemassa todellisen ongelman ratkaisemiseksi: allokaattori on olemassa, joten sinun ei tarvitse tehdä järjestelmäkutsuja jokaiselle allokoinnille. Virtuaalinen muistijärjestelmä on olemassa, joten sinun ei tarvitse hallita fyysistä muistia suoraan. Sivuvirheiden käsittelijä on olemassa, joten muisti on sitoutunut laiskasti ja tehokkaasti. Jokainen kerros vaihtaa pienen määrän läpinäkyvyyttä suureen suorituskykyyn ja käyttömukavuuteen.
Luotettavimpia ja tehokkaimpia järjestelmiä rakentavat kehittäjät, jotka ymmärtävät nämä tasot – ei siksi, että heidän pitäisi ajatella niitä jatkuvasti, vaan siksi, että kun jotain odottamatonta tapahtuu (kuten salaperäinen 72 kt:n varaus), heillä on mentaalinen malli ymmärtääkseen miksi. Rakennatpa reaaliaikaista kaupankäyntijärjestelmää, pelimoottoria tai tuhansia käyttäjiä palvelevaa yritysalustaa, kyky päätellä, mitä koodisi todella tekee järjestelmätasolla, erottaa pätevät kehittäjät poikkeuksellisista. 72 KB ei ole bugi. Se on allokaattorisi, joka tekee työnsä loistavasti.
Rakenna yrityksesi käyttöjärjestelmä jo tänään
Frelancereista toimistoihin Mewayz tarjoaa yli 138 000 yritystä 207 integroidulla moduulilla. Aloita ilmaiseksi, päivitä, kun kasvat.
Luo ilmainen tili →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
Bluesky has been dealing with a DDoS attack for nearly a full day
Apr 17, 2026
Hacker News
Human Accelerated Region 1
Apr 17, 2026
Hacker News
Discourse Is Not Going Closed Source
Apr 17, 2026
Hacker News
Substrate AI Is Hiring Harness Engineers
Apr 17, 2026
Hacker News
US Bill Mandates On-Device Age Verification
Apr 17, 2026
Hacker News
Show HN: SPICE simulation → oscilloscope → verification with Claude Code
Apr 17, 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