Hacker News

Miért mindig 72 KB az első C++ (m)allokáció?

Fedezze fel, hogy az első C++ memóriakiosztás miért kér 72 KB-ot a várt bájtok helyett. Fedezze fel a malloc belső és az operációs rendszer memóriakezelési rétegeit.

7 min read

Mewayz Team

Editorial Team

Hacker News

Az első C++ kiosztás mögött rejlő rejtély

Írsz egy egyszerű C++ programot. Egyetlen új int. Négy bájt. Beindítja a strace-t vagy kedvenc memóriaprofilját, és ott van – a folyamat éppen nagyjából 72 KB-ot kért az operációs rendszertől. Nem 4 bájt. Nem 64 bájt. Teljes 72 KB. Ha valaha is bámulta ezt a számot, és azon töprengett, hogy a szerszámai hazudtak-e, akkor nincs egyedül. Ez a látszólag bizarr viselkedés az egyik leggyakrabban feltett kérdés azon C++ fejlesztők körében, akik először kutatnak a memória belsejébe, és a válasz egy lenyűgöző utazásra vezet a kód és a tényleges hardver között elhelyezkedő rétegeken keresztül.

Mi történik, ha újat hív

A 72 KB-os adat megértéséhez nyomon kell követnie a teljes kiosztási láncot. Amikor a C++ kód végrehajtja az új int parancsot, a fordító ezt a new operátor hívására fordítja, amely a legtöbb Linux rendszeren átadja a malloc-ot a glibc-ből. De a malloc nem kér közvetlenül a kerneltől 4 bájt memóriát. A kernel lapokban működik – jellemzően 4 KB x86_64-en –, és egy rendszerhívás költsége óriási az egyszerű memória-hozzáféréshez képest. A brk() vagy mmap() meghívása minden egyes kiosztáshoz minden nem triviális programot leállítana.

Ehelyett a glibc memóriaelosztója – a ptmalloc2 nevű implementáció, amely maga Doug Lea klasszikus dlmalloc-jából származik – közvetítőként működik. Előzetesen nagy memóriablokkokat kér a kerneltől, majd kisebb darabokra faragja őket, ahogy a programodnak szüksége van rájuk. Ez az alapvető oka annak, hogy az első 4 bájtos kiosztás sokkal nagyobb kérést indít el az operációs rendszer felé. Az elosztó nem pazarol. Ez stratégiai jellegű.

A 72 KB boncolgatása: Hova mennek a bájtok

A kezdeti lefoglalási többlet több különálló összetevőből származik, amelyeket a futási környezetnek inicializálnia kell, mielőtt akár egyetlen bájt használható memóriát is átadhatna Önnek. Az egyes összetevők megértése megmagyarázza, hogy a szám miért kerül oda, ahol.

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

Először is, a glibc malloc-ja inicializálja a fő arénát – az elsődleges könyvelési struktúrát, amely nyomon követi a főszálon lévő összes allokációt. Ez az aréna tartalmazza a kupac metaadatait, a szabad listás mutatókat és a különböző kiosztási méretekhez tartozó társzerkezeteket. Az allokátor meghosszabbítja a programtörést az sbrk() segítségével, és a kezdeti kiterjesztést az M_TOP_PAD nevű belső paraméter szabályozza, amely alapértelmezés szerint 128 KB kitöltés. A tényleges kezdeti kérés azonban az oldaligazításhoz és a meglévő töréspozícióhoz igazodik, ami gyakran kisebb első kérést eredményez – általában a 72 KB-os érték közelében landol egy frissen indított folyamat során.

Másodszor, a glibc 2.26 óta az allokátor az első használatkor inicializál egy szál helyi gyorsítótárat (tcache). A tcache 64 tárolót tartalmaz (egy kis kiosztású méretosztályonként), amelyek mindegyike legfeljebb 7 gyorsítótárban tárolt darab tárolására képes. Maga a tcache_perthread_struct körülbelül 1 KB-ot fogyaszt, de az inicializálása elindítja a szélesebb aréna beállítását. Harmadszor, a C++ futtatókörnyezet már végrehajtott lefoglalásokat, mielőtt a main() még lefutna – a statikus konstruktorok, az iostream puffer inicializálása az std::cout és a friends számára, valamint a területi beállítások mind hozzájárulnak ehhez a kezdeti halom lábnyomhoz.

Az arénarendszer és miért okos az előzetes kiosztás?

Az a döntés, hogy előre lefoglalunk egy jelentős memóriadarabot ahelyett, hogy részenként kérnénk le, nem véletlen a megvalósítás. Ez egy szándékos mérnöki kompromisszum, amely több évtizedes rendszerprogramozási tapasztalatban gyökerezik. A brk() vagy mmap() minden hívása magában foglalja a felhasználói területről a kernelterületre való kontextusváltást, a folyamat virtuális memória-leképezéseinek módosítását és az oldaltábla esetleges frissítéseit. A modern hardvereken egyetlen rendszerhívás nagyjából 100-200 nanomásodpercbe kerül – önmagában véve triviális, méreteiben katasztrofális.

Vegyünk egy olyan programot, amely 10 000 kis kiosztást végez az inicializálás során. Előzetes kiosztás nélkül ez 10 000 rendszerhívást jelentene, ami hozzávetőlegesen 1-2 milliszekundum tiszta többletköltséget jelent. Aréna alapú allokátorral az első kiosztás trigg

Build Your Business OS Today

From freelancers to agencies, Mewayz powers 138,000+ businesses with 208 integrated modules. Start free, upgrade when you grow.

Create Free Account →
and ending with:

Frequently Asked Questions

Miért pontosan 72 KB a megszabott méret?

Az 72 KB nem véletlen. Ez az operációs rendszer által kiosztott alapértelmezett oldall mérete (page size) és a memória kezelő rendszer belső implementációjából fakad. A modern rendszerben az memória kiosztás minimálisan egy oldallal történik, így az első kérés legalább egy teljes oldalt fog kapni, ami tipikusan 4096 bájt (4 KB) vagy 64 KB lehet, de a C++ standard könyvtár belső szerkezet miatt az 72 KB-ot kéri, hogy elegendő helyet biztosítson a metaadatok és belső kezelési strukúráinak.

Hogyan lehet elkerülni ezt a "paduletet"?smalloc() használatával?

A smalloc() nem standard C++ könyvtár funkció, de a memóriakezelés optimálisanál lehetővé teszi a kicsi objektumok kezelését. Mewayz rendszerében, amely 208 modulja $49/mo áron elérhető, ilyen kis memóriakezelési problémákra specializált szoftverfejlesztési eszközeket nyújthat. Az elsődleges megoldás a belső memóriakezelő implementációja a kisebb kiosztásokat külön kezelő pufferben tartja, így nem kell mindig 72 KB-t kérni az operációs rendszertől.

Melyik C++ standard keveredésének köszönhetjük ezt a viselkedést?

Ez a viselkedés a C++11 standard bevezetésével vált általánosabbá, amikor a standard könyvtár implementációi (mint a libstdc++ és libc++) a jobb teljesítmény érdekében bevezették a belső memóriakezelést. Az előző standardok (C++03 és régebbi) gyakran közvetlen

Try Mewayz Free

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

Start Free Try Demo

Start managing your business smarter today

Join 30,000+ businesses. Free forever plan · No credit card required.

Start Free → Watch Demo
Found this useful? Share it.
X / Twitter LinkedIn Facebook WhatsApp

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

Seed of Might Color Correction Process (2023) [pdf]

Mar 8, 2026

Hacker News

A Meta mesterséges intelligens szemüvege és adatvédelmi aggályai

Mar 8, 2026

Hacker News

Thomas Mann újraalkotása

Mar 8, 2026

Hacker News

HN show: A semmiből építettem egy 500 ms alatti késleltetésű hangügynököt

Mar 8, 2026

Hacker News

Brit Columbia állandóan bevezeti a nappali időt

Mar 8, 2026

Hacker News

Xous biztonságra összpontosító nyílt forráskódú, 22 nm-es egyedi szilícium

Mar 8, 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