Fahami strategi peruntukan memori Linux dalam satu artikel
Apakah rupa pengedaran memori proses Linux?
Dalam sistem pengendalian Linux, bahagian dalam ruang alamat maya dibahagikan kepada dua bahagian: ruang kernel dan ruang pengguna Sistem dengan digit yang berbeza mempunyai julat ruang alamat yang berbeza. Sebagai contoh, sistem 32-bit dan 64-bit yang paling biasa adalah seperti berikut:

Anda boleh lihat di sini:
- Ruang kernel sistem 32-bit menduduki 1G, yang berada di bahagian atas, dan baki 3G adalah ruang pengguna
- Ruang kernel dan ruang pengguna sistem 64-bit adalah kedua-duanya 128T, masing-masing menduduki bahagian tertinggi dan terendah keseluruhan ruang memori, dan bahagian tengah yang tinggal tidak ditentukan.
Mari kita bincangkan tentang perbezaan antara ruang kernel dan ruang pengguna:
- Apabila proses berada dalam mod pengguna, ia hanya boleh mengakses memori ruang pengguna
- Hanya selepas memasuki keadaan kernel anda boleh mengakses memori dalam ruang kernel
Walaupun setiap proses mempunyai memori maya bebasnya sendiri, Alamat kernel dalam setiap memori maya sebenarnya dikaitkan dengan memori fizikal yang sama. Dengan cara ini, selepas proses bertukar kepada keadaan kernel, ia boleh mengakses memori ruang kernel dengan mudah.

Seterusnya, mari kita ketahui lebih lanjut tentang pembahagian ruang maya dan ruang kernel dibahagikan dengan cara yang berbeza.
Mari kita lihat pengagihan ruang pengguna dengan mengambil sistem 32-bit sebagai contoh, saya melukis gambar untuk mewakili hubungan mereka:
.Anda boleh lihat dari gambar ini bahawa memori ruang pengguna dibahagikan kepada 6 segmen memori berbeza dari rendah ke tinggi:

- Segmen fail program, termasuk kod boleh laku binari
- Segmen data yang dimulakan, termasuk pemalar statik
- Segmen data yang tidak dimulakan, termasuk pembolehubah statik yang tidak dimulakan
- Segmen timbunan, termasuk memori yang diperuntukkan secara dinamik, bermula dari alamat rendah dan berkembang ke atas
- Segmen pemetaan fail, termasuk perpustakaan dinamik, memori kongsi, dll., bermula dari alamat rendah dan berkembang ke atas (bergantung pada versi perkakasan dan kernel ).
- Segmen tindanan, termasuk pembolehubah tempatan dan konteks panggilan fungsi, dsb. Saiz tindanan ditetapkan, biasanya 8 MB. Sudah tentu, sistem juga menyediakan parameter supaya kita boleh menyesuaikan saiz
Di antara 6 segmen memori ini, memori segmen pemetaan timbunan dan fail diperuntukkan secara dinamik. Contohnya, menggunakan malloc() atau mmap() pustaka standard C, anda boleh memperuntukkan memori secara dinamik dalam segmen pemetaan timbunan dan fail masing-masing.
Bagaimanakah malloc memperuntukkan memori?
Sebenarnya, malloc() bukan panggilan sistem, tetapi fungsi dalam perpustakaan C, digunakan untuk memperuntukkan memori secara dinamik.
Apabila malloc menggunakan memori, terdapat dua cara untuk memohon memori timbunan daripada sistem pengendalian.
- Kaedah 1: Peruntukkan memori daripada timbunan melalui panggilan sistem brk()
- Kaedah 2: Peruntukkan memori dalam kawasan pemetaan fail melalui panggilan sistem mmap()
Pelaksanaan kaedah satu sangat mudah, iaitu menggunakan fungsi brk() untuk mengalihkan penunjuk "top of heap" ke alamat tinggi untuk mendapatkan ruang ingatan baharu. Seperti yang ditunjukkan di bawah:

Kaedah 2 menggunakan kaedah "pemetaan tanpa nama persendirian" dalam panggilan sistem mmap() untuk memperuntukkan sekeping memori dalam kawasan pemetaan fail, iaitu untuk "mencuri" sekeping memori daripada kawasan pemetaan fail. Seperti yang ditunjukkan di bawah:

"
Dalam keadaan apakah malloc() memperuntukkan memori melalui brk()? Dalam senario apakah memori diperuntukkan melalui mmap()?
”
malloc() mempunyai ambang yang ditentukan secara lalai dalam kod sumber:
- Jika memori yang diperuntukkan oleh pengguna kurang daripada 128 KB, mohon memori melalui brk(
- Jika memori yang diperuntukkan oleh pengguna lebih besar daripada 128 KB, mohon memori melalui mmap(
Perhatikan bahawa versi glibc yang berbeza mentakrifkan ambang yang berbeza.
malloc() memperuntukkan ingatan fizikal?
Tidak, malloc() memperuntukkan memori maya.
Jika memori maya yang diperuntukkan tidak diakses, memori maya tidak akan dipetakan ke memori fizikal, jadi ia tidak akan menduduki memori fizikal.
Hanya apabila mengakses ruang alamat maya yang diperuntukkan, sistem pengendalian mencari jadual halaman dan mendapati halaman yang sepadan dengan memori maya tidak berada dalam memori fizikal Ia akan mencetuskan gangguan halaman, dan kemudian sistem pengendalian akan mewujudkan a pautan antara ingatan maya dan hubungan pemetaan fizikal antara.
Berapa banyak memori maya yang akan diperuntukkan oleh malloc(1)?
Apabilamalloc() memperuntukkan memori, ia tidak memperuntukkan ruang memori mengikut bilangan bait yang dijangkakan oleh pengguna, tetapi pra-peruntukkan ruang yang lebih besar sebagai kolam memori.
Jumlah ruang khusus yang akan diperuntukkan terlebih dahulu adalah berkaitan dengan pengurus memori yang digunakan oleh malloc Kami akan menggunakan pengurus memori lalai malloc (Ptmalloc2) untuk menganalisis.
Seterusnya, mari lakukan percubaan dan gunakan kod berikut untuk melihat berapa banyak ruang memori yang sebenarnya diperuntukkan oleh sistem pengendalian apabila memohon 1 bait memori melalui malloc.
#include #include int main() { printf("使用cat /proc/%d/maps查看内存分配\n",getpid()); //申请1字节的内存 void *addr = malloc(1); printf("此1字节的内存起始地址:%x\n", addr); printf("使用cat /proc/%d/maps查看内存分配\n",getpid()); //将程序阻塞,当输入任意字符时才往下执行 getchar(); //释放内存 free(addr); printf("释放了1字节的内存,但heap堆并不会释放\n"); getchar(); return 0; }
Laksanakan kod (Biar saya terangkan terlebih dahulu, versi perpustakaan glibc yang saya gunakan ialah 2.17):

Kita boleh melihat pengedaran memori proses melalui fail /proc//maps. Saya menapis julat alamat memori dalam fail peta dengan alamat permulaan memori 1-bait ini.
[root@xiaolin ~]# cat /proc/3191/maps | grep d730 00d73000-00d94000 rw-p 00000000 00:00 0 [heap]
Memori yang diperuntukkan dalam contoh ini adalah kurang daripada 128 KB, jadi memori digunakan pada ruang timbunan melalui panggilan sistem brk(), supaya anda boleh melihat tanda [timbunan] di hujung kanan.
Anda dapat melihat bahawa julat alamat memori bagi ruang timbunan ialah 00d73000-00d94000, dan saiz julat ini ialah 132KB, yang bermaksud bahawa malloc(1) sebenarnya pra-peruntukkan 132K bait memori.
Sesetengah pelajar mungkin perasan bahawa alamat permulaan memori yang dicetak dalam program ialah d73010, manakala fail peta menunjukkan bahawa alamat permulaan ruang ingatan timbunan ialah d73000 Mengapakah terdapat tambahan 0x10 (16 bait)? Mari tinggalkan soalan ini buat masa ini dan bincangkannya kemudian.
#percuma Adakah memori yang dibebaskan akan dikembalikan kepada sistem pengendalian?
Mari kita laksanakan proses di atas untuk melihat sama ada memori timbunan masih ada selepas memori dikeluarkan melalui fungsi free()?

Seperti yang anda boleh lihat dari gambar di bawah, selepas membebaskan memori, ingatan timbunan masih wujud dan belum dikembalikan ke sistem pengendalian.

Ini kerana daripada melepaskan 1 bait ini kepada sistem pengendalian, adalah lebih baik untuk menyimpannya di cache dan memasukkannya ke dalam kumpulan memori malloc Apabila proses itu digunakan untuk 1 bait memori sekali lagi, ia boleh digunakan semula secara langsung, yang mana adalah lebih pantas.
Sudah tentu, apabila proses keluar, sistem pengendalian akan menuntut semula semua sumber proses.
Memori timbunan masih wujud selepas ingatan bebas yang dinyatakan di atas adalah untuk ingatan yang digunakan oleh malloc melalui brk().
Jika malloc memohon memori melalui mmap, ia akan dikembalikan kepada sistem pengendalian selepas membebaskan memori secara percuma.
Mari kita lakukan percubaan untuk mengesahkan bahawa kita memohon 128 KB memori melalui malloc, supaya malloc memperuntukkan memori melalui mmap.
#include #include int main() { //申请1字节的内存 void *addr = malloc(128*1024); printf("此128KB字节的内存起始地址:%x\n", addr); printf("使用cat /proc/%d/maps查看内存分配\n",getpid()); //将程序阻塞,当输入任意字符时才往下执行 getchar(); //释放内存 free(addr); printf("释放了128KB字节的内存,内存也归还给了操作系统\n"); getchar(); return 0; }
Kod pelaksanaan:

Melihat pada pengedaran memori proses, anda boleh mendapati bahawa tiada tanda [kepala] di hujung kanan, menunjukkan bahawa memori tanpa nama diperuntukkan daripada kawasan pemetaan fail melalui mmap melalui pemetaan tanpa nama.

Kemudian mari kita bebaskan ingatan ini dan lihat:

Semak alamat permulaan memori 128 KB sekali lagi dan anda boleh mendapati ia tidak lagi wujud, menunjukkan bahawa ia telah dikembalikan kepada sistem pengendalian.

Berkenaan soalan "Adakah memori yang dipohon oleh malloc dan dikeluarkan secara percuma akan dikembalikan ke sistem pengendalian?", kita boleh membuat ringkasan:
- Memori yang digunakan oleh malloc melalui brk(), apabila bebas mengeluarkan memori, tidak akan mengembalikan memori ke sistem pengendalian, tetapi akan dicache dalam kolam memori malloc untuk kegunaan seterusnya Apabila percuma membebaskan memori yang diperuntukkan oleh malloc melalui
- mmap(), akan mengembalikan memori kepada sistem pengendalian, dan memori benar-benar dikeluarkan.
Kenapa tidak semua menggunakan mmap untuk memperuntukkan memori?
Oleh kerana memohon memori daripada sistem pengendalian memerlukan panggilan sistem Untuk melaksanakan panggilan sistem, anda perlu memasukkan keadaan kernel, dan kemudian kembali ke keadaan pengguna.Jadi, operasi memohon memori harus mengelakkan panggilan sistem yang kerap Jika mmap digunakan untuk memperuntukkan memori, bermakna panggilan sistem mesti dilaksanakan setiap kali.
Selain itu, kerana memori yang diperuntukkan oleh mmap akan dikembalikan kepada sistem pengendalian setiap kali ia dikeluarkan, jadi alamat maya yang diperuntukkan oleh mmap berada dalam keadaan kesalahan halaman setiap kali, dan kemudian apabila alamat maya diakses untuk yang pertama masa, ia akan dicetuskan gangguan halaman.
Dalam erti kata lain,
jika memori kerap diperuntukkan melalui mmap, bukan sahaja keadaan berjalan akan ditukar setiap kali, malah gangguan halaman juga akan berlaku (selepas akses pertama ke alamat maya), yang akan menghasilkan CPU yang besar penggunaan.
Untuk memperbaiki kedua-dua masalah ini, apabila malloc menggunakan memori dalam ruang timbunan melalui panggilan sistem brk(), memandangkan ruang timbunan berterusan, ia secara langsung memperuntukkan memori yang lebih besar sebagai kumpulan memori apabila memori dilepaskan , ia Dicache dalam kolam memori.
Apabila anda memohon memori pada masa akan datang, cuma keluarkan blok memori yang sepadan terus dari kumpulan memori, dan hubungan pemetaan antara alamat maya dan alamat fizikal blok memori ini bukan sahaja mengurangkan bilangan panggilan sistem, Ia juga mengurangkan bilangan gangguan halaman, yang akan sangat mengurangkan penggunaan CPU.
Memandangkan brk sangat hebat, mengapa tidak menggunakan brk untuk semua peruntukan?
Kami menyebut sebelum ini bahawa memori yang diperuntukkan dari ruang timbunan melalui brk tidak akan dikembalikan kepada sistem pengendalian, jadi mari kita pertimbangkan senario sedemikian.Jika kita memohon tiga keping memori 10k, 20k, dan 30k berturut-turut, jika 10k dan 20k dilepaskan dan menjadi ruang ingatan percuma, jika memori yang digunakan untuk kali seterusnya kurang daripada 30k, maka ruang memori percuma ini boleh digunakan semula .

Oleh itu, memandangkan sistem kerap mallocs dan membebaskan, terutamanya untuk blok kecil memori, semakin banyak serpihan yang tidak boleh digunakan akan dijana dalam timbunan, yang membawa kepada "kebocoran memori". Fenomena "kebocoran" ini tidak dapat dikesan menggunakan valgrind.
Jadi, dalam pelaksanaan malloc, perbezaan, kebaikan dan keburukan dalam tingkah laku brk dan mmap dipertimbangkan sepenuhnya, dan blok memori yang besar (128KB) diperuntukkan secara lalai sebelum mmap digunakan untuk memperuntukkan ruang memori.
Fungsi free() hanya lulus dalam alamat memori Mengapa ia boleh tahu berapa banyak memori yang perlu dikosongkan?
Ingat, saya nyatakan sebelum ini bahawa alamat permulaan memori yang dikembalikan kepada mod pengguna oleh malloc adalah 16 bait lebih daripada alamat permulaan ruang timbunan proses?
16 bait tambahan menyimpan maklumat perihalan blok memori, seperti saiz blok memori.

Dengan cara ini, apabila fungsi free() dilaksanakan, free akan mengimbangi alamat memori masuk sebanyak 16 bait ke kiri, dan kemudian menganalisis saiz blok memori semasa daripada 16 bait ini, dan secara semula jadi mengetahui betapa besarnya perlu dilepaskan ingatan.
Atas ialah kandungan terperinci Fahami strategi peruntukan memori Linux dalam satu artikel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

DeepSeek adalah alat carian dan analisis pintar yang kuat yang menyediakan dua kaedah akses: versi web dan laman web rasmi. Versi web adalah mudah dan cekap, dan boleh digunakan tanpa pemasangan; Sama ada individu atau pengguna korporat, mereka dapat dengan mudah mendapatkan dan menganalisis data besar-besaran melalui DeepSeek untuk meningkatkan kecekapan kerja, membantu membuat keputusan dan menggalakkan inovasi.

Terdapat banyak cara untuk memasang DeepSeek, termasuk: Menyusun dari Sumber (untuk pemaju berpengalaman) menggunakan pakej yang dikompilasi (untuk pengguna Windows) menggunakan bekas docker (untuk yang paling mudah, tidak perlu bimbang tentang keserasian) Dokumen rasmi dengan berhati -hati dan menyediakannya sepenuhnya untuk mengelakkan masalah yang tidak perlu.

Bitget adalah pertukaran cryptocurrency yang menyediakan pelbagai perkhidmatan perdagangan termasuk perdagangan tempat, perdagangan kontrak dan derivatif. Ditubuhkan pada tahun 2018, pertukaran itu beribu pejabat di Singapura dan komited untuk menyediakan pengguna dengan platform perdagangan yang selamat dan boleh dipercayai. Bitget menawarkan pelbagai pasangan perdagangan, termasuk BTC/USDT, ETH/USDT dan XRP/USDT. Di samping itu, pertukaran mempunyai reputasi untuk keselamatan dan kecairan dan menawarkan pelbagai ciri seperti jenis pesanan premium, perdagangan leverage dan sokongan pelanggan 24/7.

Ouyi Okx, pertukaran aset digital terkemuka di dunia, kini telah melancarkan pakej pemasangan rasmi untuk menyediakan pengalaman perdagangan yang selamat dan mudah. Pakej pemasangan OKX OUYI tidak perlu diakses melalui penyemak imbas. Proses pemasangan adalah mudah dan mudah difahami.

Gate.io adalah pertukaran cryptocurrency yang popular yang boleh digunakan pengguna dengan memuat turun pakej pemasangannya dan memasangnya pada peranti mereka. Langkah -langkah untuk mendapatkan pakej pemasangan adalah seperti berikut: Lawati laman web rasmi Gate.io, klik "Muat turun", pilih sistem operasi yang sepadan (Windows, Mac atau Linux), dan muat turun pakej pemasangan ke komputer anda. Adalah disyorkan untuk mematikan perisian antivirus atau firewall sementara semasa pemasangan untuk memastikan pemasangan yang lancar. Selepas selesai, pengguna perlu membuat akaun Gate.io untuk mula menggunakannya.

Ouyi, juga dikenali sebagai Okx, adalah platform perdagangan cryptocurrency terkemuka di dunia. Artikel ini menyediakan portal muat turun untuk pakej pemasangan rasmi Ouyi, yang memudahkan pengguna memasang klien OUYI pada peranti yang berbeza. Pakej pemasangan ini menyokong sistem Windows, Mac, Android dan iOS. Selepas pemasangan selesai, pengguna boleh mendaftar atau log masuk ke akaun OUYI, mula membuat kriptografi perdagangan dan nikmati perkhidmatan lain yang disediakan oleh platform.

Gate.io adalah platform perdagangan cryptocurrency yang sangat terkenal yang dikenali sebagai pemilihan token yang luas, yuran transaksi yang rendah dan antara muka yang mesra pengguna. Dengan ciri -ciri keselamatan lanjutan dan perkhidmatan pelanggan yang cemerlang, Gate.io menyediakan peniaga dengan persekitaran perdagangan cryptocurrency yang boleh dipercayai dan mudah. Jika anda ingin menyertai Gate.io, sila klik pautan yang disediakan untuk memuat turun pakej pemasangan pendaftaran rasmi untuk memulakan perjalanan perdagangan cryptocurrency anda.

Tutorial ini membimbing anda melalui memasang dan mengkonfigurasi nginx dan phpmyadmin pada sistem Ubuntu, berpotensi bersama pelayan Apache yang sedia ada. Kami akan meliputi penubuhan nginx, menyelesaikan potensi konflik pelabuhan dengan Apache, memasang MariaDB (
