Wêrom is de earste C++ (m) allocaasje altyd 72 KB? | Mewayz Blog Skip to main content
Hacker News

Wêrom is de earste C++ (m) allocaasje altyd 72 KB?

Comments

10 min read Via joelsiks.com

Mewayz Team

Editorial Team

Hacker News

It mystearje efter jo earste C++-tawizing

Jo skriuwe in ienfâldich C++ programma. In inkele nije int. Fjouwer bytes. Jo stjoere strace of jo favorite ûnthâldprofiler op, en dêr is it - jo proses hat gewoan sawat 72 KB oanfrege fan it bestjoeringssysteem. Net 4 bytes. Net 64 bytes. In folsleine 72 KB. As jo ​​​​oait nei dat nûmer stoarre hawwe en jo ôffrege hawwe oft jo ark foar jo lei, dan binne jo net allinich. Dit skynber bizarre gedrach is ien fan 'e meast stelde fragen ûnder C++-ûntwikkelders dy't foar it earst yn ynterne ûnthâld graven, en it antwurd nimt ús mei op in fassinearjende reis troch de lagen dy't sitte tusken jo koade en de eigentlike hardware.

Wat bart der as jo nij

belje

Om it sifer fan 72 KB te begripen, moatte jo de folsleine allocaasjeketen folgje. As jo ​​​​C++-koade nij int útfiert, fertaalt de kompilator dat yn in oprop oan operator nij, dy't op de measte Linux-systemen delegearret nei malloc fan glibc. Mar malloc freget de kernel net direkt foar 4 bytes fan ûnthâld. De kernel wurket yn siden - typysk 4 KB op x86_64 - en de kosten fan in systeemoprop binne enoarm relatyf oan in ienfâldige ûnthâld tagong. It oproppen fan brk() of mmap() foar elke yndividuele tawizing soe elk net-triviale programma stil meitsje.

Ynstee, glibc syn ûnthâld allocator - in ymplemintaasje neamd ptmalloc2, sels ôfkomstich fan Doug Lea syn klassike dlmalloc - fungearret as in middelman. It freget foarôf grutte blokken ûnthâld fan 'e kernel, snijt se dan yn lytsere stikken as jo programma se nedich is. Dit is de fûnemintele reden dat jo earste 4-byte-allokaasje in folle grutter fersyk oan it bestjoeringssysteem trigger. De allocator is net fergriemd. It wurdt strategysk.

De 72 KB ûntsiferje: wêr't de bytes gean

De inisjele allocaasje-overhead komt fan ferskate ûnderskate komponinten dy't de runtime inisjalisearje moat foardat it jo sels in inkele byte fan brûkber ûnthâld kin leverje. It begripen fan elke komponint ferklearret wêrom't it oantal lânet wêr't it docht.

Earst initialisearret de malloc fan glibc de haad arena - de primêre boekhâldingstruktuer dy't alle allocaasjes op 'e haadthread folget. Dizze arena omfettet metadata foar de heap, oanwizers foar frije list, en binstruktueren foar ferskate tawizingsgrutte. De allocator ferlingt it programma break fia sbrk(), en de earste útwreiding wurdt regele troch in ynterne parameter neamd M_TOP_PAD, dy't standert is op 128 KB fan padding. It eigentlike inisjele fersyk wurdt lykwols oanpast foar side-ôfstimming en besteande pauzeposysje, wat faak resultearret yn in lytser earste fersyk - gewoanwei lâning tichtby dat 72 KB-figuer op in nij begon proses.

Twadde, sûnt glibc 2.26, initialisearret de allocator in thread-local cache (tcache) by it earste gebrûk. De tcache befettet 64 bakken (ien per lytse tawizing grutte klasse), elk by steat om te hâlden maksimaal 7 cached brokken. De tcache_perthread_struct sels konsumearret sawat 1 KB, mar de aksje fan it inisjalisearjen triggert de bredere arena-opset. Tredde, de C++-runtime hat al allocaasjes útfierd foardat jo haad() sels rint - statyske konstruktors, iostream-bufferinitialisaasje foar std::cout en freonen, en lokale opset drage allegear by oan dy earste heap-footprint.

It Arena-systeem en wêrom foarôfdieling tûk is

It beslút om in substansjeel stik ûnthâld foarôf te tawizen yn plak fan it stikje te freegjen is gjin tafal fan ymplemintaasje. It is in opsetlike technyk ôfwikseling woartele yn tsientallen jierren fan ûnderfining fan systeemprogrammearring. Elke oprop nei brk() of mmap() omfettet in kontekstwikseling fan brûkersromte nei kernelromte, wiziging fan de firtuele ûnthâldmappings fan it proses, en potinsjele sidetabel-updates. Op moderne hardware kostet ien systeemoprop rûchwei 100-200 nanosekonden - triviaal yn isolemint, katastrofaal op skaal.

Besjoch in programma dat 10.000 lytse allocaasjes makket by inisjalisaasje. Sûnder pre-allokaasje soe dat 10.000 systeemoproppen betsjutte, sawat 1-2 millisekonden fan suvere overhead kostje. Mei in arena-basearre allocator triggert de earste allocaasje in inkele systeemoprop, en de folgjende 9,999 allocaasjes wurde folslein yn brûkersromte betsjinne troch oanwizer arithmetic en keppele list operaasjes - elk nimt sawat 10-50 nanosekonden. De wiskunde is ûndûbelsinnich: pre-allokaasje wint troch oarders fan grutte.

De 72 KB dy't jo sjogge by jo earste allokaasje is gjin fergriemd ûnthâld - it is in ynvestearring yn prestaasjes. De allocator weddet op dat jo programma gau mear allocaasjes sil meitsje, en yn praktysk elk senario yn 'e echte wrâld betellet dy weddenskip geweldich út. De kosten fan net brûkte firtuele adresromte binne yn essinsje nul op moderne 64-bit systemen.

Firtueel ûnthâld tsjin fysyk ûnthâld: wêrom makket it net út

In mienskiplike soarch ûnder ûntwikkelders dy't dit gedrach foar it earst tsjinkomme is boarneôffal. As ik mar 4 bytes nedich haw, wêrom ferbrûkt myn programma 72 KB? It krityske ynsjoch is dat firtuele ûnthâld is gjin fysyk ûnthâld. As glibc de programmapauze ferlingt mei 72 KB, fernijt de kernel de firtuele ûnthâldmappings fan it proses, mar it makket dizze siden net fuortendaliks werom mei fysike RAM. De eigentlike fysike siden wurde op oanfraach tawiisd troch sidefouten - allinich as jo programma nei in spesifyk adres skriuwt, jout de kernel der in echte side fan ûnthâld oan.

💡 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 →

Dit betsjut dat ek al nimt de firtuele grutte fan jo proses mei 72 KB ta, de resident set size (RSS) - de hoemannichte fysike RAM dy't wirklik konsumearre is - ferheget mei allinich de siden dy't jo werklik oanreitsje. Foar ien nije int is dat typysk ien side fan 4 KB, plus hokker siden de arena-metadata beslacht. De oerbleaune firtuele romte sit dêr, klear foar gebrûk, en kostet neat oars as adresromte - wêrfan jo 128 TB hawwe op in 64-bit Linux-systeem.

Dit ûnderskied is kritysk by it profilearjen en kontrolearjen fan produksjeapplikaasjes. As jo ​​software bouwe dy't echte boarneferbrûk folgje moat - of it no in SaaS-backend, in mikrotsjinst, of in analytyske pipeline is lykas dejingen dy't rinne op platfoarms lykas Mewayzfoar saaklike operaasjes - jo moatte altyd RSS kontrolearje ynstee fan firtuele grutte. Tools lykas /proc/[pid]/smaps, valgrind --tool=massif, en pmap kinne jo krekte fysike ûnthâldfuotprinten jaan ynstee fan misleidende firtuele ûnthâldfigueren.

Hoe ferskillende allocators de earste tawizing behannelje

It sifer fan 72 KB is spesifyk foar glibc's ptmalloc2. Oare allocators meitsje ferskillende tradeoffs, en de inisjele allocaasje-overhead feroaret neffens. Begryp fan dizze ferskillen is weardefol by it kiezen fan in allocator foar prestaasjegefoelige applikaasjes.

  • jemalloc (brûkt troch Facebook, FreeBSD) - Brûkt in mear korrelige arenastruktuer mei thread-lokale caches. De inisjele overhead hat de neiging heger te wêzen (faak 200+ KB), mar leveret bettere multi-threaded prestaasjes troch fermindere slûskonflikten.
  • tcmalloc (Google's Thread-Caching Malloc) - Jout standert in per-thread-cache fan sawat 2 MB ta, mei agressive pre-allokaasje. Inisjele overhead is heger, mar lettere lytse allocaasjes binne ekstreem fluch.
  • musl libc's malloc — Brûkt in folle ienfâldiger ûntwerp basearre op mmap foar alle allocaasjes. De earste overhead is minimaal (faak mar 4 KB per tawizing), mar de kosten per tawizing binne heger fanwege faker systeemoproppen.
  • mimalloc (Microsoft) - Brûkt segment-basearre tawizing mei 64 MB segminten. De earste allocaasje triggert in firtuele reservearring fan 64 MB (mei minimale fysike ynset), hannelsadresromte foar útsûnderlike lokaasje en trochset.

De kar tusken dizze allocators hinget folslein ôf fan jo wurkdruk. Foar langrinnende serverapplikaasjes mei swiere multi-threaded allocaasje, prestearret jemalloc of tcmalloc typysk de standert fan glibc. Foar ûnthâld-beheinde ynbêde systemen kin de ienfâldiger oanpak fan musl de foarkar wêze nettsjinsteande legere trochslach. Foar de measte buroblêd- en serverapplikaasjes foar algemiene doelen fertsjintwurdiget de initial overhead fan 72 KB fan ptmalloc2 in ridlike standert dy't goed wurket sûnder ôfstimmen.

It earste tawizingsgedrach ôfstimme

As de standert 72 KB inisjele overhead wirklik problematysk is foar jo gebrûksgefal - miskien binne jo tûzenen koartlibbene prosessen opwekke, dy't elk mar in hantsjefol allocaasjes meitsje - glibc leveret ferskate tunables fia mallopt() en de MALLOC_ famylje fan omjouwingsfariabelen.

De parameter M_TOP_PAD kontrolearret hoefolle ekstra ûnthâld de allocator freget dan wat daliks nedich is. It ynstellen op 0 mei mallopt(M_TOP_PAD, 0) fertelt de allocator om allinich te freegjen wat nedich is, wat de inisjele overhead signifikant ferminderet. De parameter M_MMAP_THRESHOLD kontrolearret de grutte wêrboppe tawizings mmap brûke ynstee fan de arena. De M_TRIM_THRESHOLD kontrolearret as frijmakke ûnthâld weromjûn wurdt nei it OS. En sûnt glibc 2.26, kinne de glibc.malloc.tcache_count en glibc.malloc.tcache_max tunables jo it gedrach fan 'e thread-cache kontrolearje.

In wurd fan foarsichtigens lykwols: it ôfstimmen fan dizze parameters sûnder soarchfâldige benchmarking makket dingen hast altyd slimmer. De standerts waarden keazen op basis fan wiidweidige profilearring yn 'e echte wrâld, en se fertsjintwurdigje in swiete plak foar de grutte mearderheid fan wurkdruk. Behalven as jo sterk bewiis hawwe fan produksjeprofilearring dat malloc-overhead in knelpunt is - en jo hawwe de ynfloed fan jo wizigingen mjitten - lit de standerts allinich. Premature optimisaasje fan 'e allocator is in bysûnder ferrifeljende foarm fan yak-skeerjen dy't ûntelbere technyske oeren hat konsumearre foar ferwaarlooslik foardiel.

Wat dit ús leart oer systeemprogrammearring

It mystearje fan earste tawizing fan 72 KB is, yn syn kearn, in les oer abstraksjelagen. C++ jout jo de yllúzje dat nij int 4 bytes allocearret. Dat seit de taalnoarm. Jo mentale model seit dat. Mar tusken jo koade en de hardware sit in steapel ferfine systemen - de C++ runtime, de C-biblioteek-allokator, it firtuele ûnthâldsubsysteem fan 'e kernel, en de MMU en TLB fan 'e hardware - elk it tafoegjen fan har eigen gedrach, optimisaasjes en overhead.

Dit is gjin gebrek. It is it heule punt fan systeemsoftware. Elke laach bestiet om in echt probleem op te lossen: de allocator bestiet, sadat jo gjin systeemoproppen hoege te meitsjen foar elke allocaasje. It firtuele ûnthâldsysteem bestiet dus jo hoege net direkt fysyk ûnthâld te behearjen. De sidefoutbehandler bestiet dus ûnthâld wurdt loai en effisjint ynset. Elke laach hannelet in lyts bedrach fan transparânsje foar in grutte hoemannichte prestaasjes en gemak.

De ûntwikkelders dy't de meast betroubere, heechst prestearjende systemen bouwe, binne dejingen dy't dizze lagen begripe - net om't se konstant oer har moatte tinke, mar om't as der wat ûnferwachts bart (lykas in mysterieuze 72 KB-tadieling), hawwe se it mentale model om te begripen wêrom. Oft jo in real-time hannelsysteem bouwe, in spielmotor, of in bedriuwsplatfoarm dat tûzenen brûkers tsjinnet, de mooglikheid om te redenearjen oer wat jo koade eins docht op systeemnivo is wat kompetinte ûntwikkelders skiedt fan útsûnderlike. De 72 KB is gjin brek. It is jo allocator dy't har wurk briljant docht.

Bou hjoed jo bedriuw OS

Fan freelancers oant ynstânsjes, Mewayz macht 138.000+ bedriuwen mei 207 yntegreare modules. Begjin fergees, upgrade as jo groeie.

Fergees akkount oanmeitsje →

Try Mewayz Free

All-in-one platform for CRM, invoicing, projects, HR & more. No credit card required.

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 →

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