Apa itu fragmentasi memori?

204

Saya pernah mendengar istilah "fragmentasi memori" yang digunakan beberapa kali dalam konteks alokasi memori dinamis C ++. Saya telah menemukan beberapa pertanyaan tentang cara menangani fragmentasi memori, tetapi tidak dapat menemukan pertanyaan langsung yang berkaitan dengannya. Begitu:

  • Apa itu fragmentasi memori?
  • Bagaimana saya bisa tahu jika fragmentasi memori merupakan masalah bagi aplikasi saya? Program apa yang paling mungkin diderita?
  • Apa cara umum yang baik untuk menangani fragmentasi memori?

Juga:

  • Saya sering mendengar menggunakan alokasi dinamis yang dapat meningkatkan fragmentasi memori. Apakah ini benar? Dalam konteks C ++, saya memahami semua kontainer standar (std :: string, std :: vector, dll) menggunakan alokasi memori dinamis. Jika ini digunakan di seluruh program (terutama std :: string), apakah fragmentasi memori lebih cenderung menjadi masalah?
  • Bagaimana fragmentasi memori dapat ditangani dalam aplikasi yang beratnya STL?
AshleysBrain
sumber
1
Banyak jawaban bagus, terima kasih semuanya!
AshleysBrain
4
Sudah ada banyak jawaban bagus, tetapi berikut adalah beberapa gambar dari aplikasi aktual (Firefox) di mana fragmentasi memori menjadi masalah besar: blog.pavlov.net/2007/11/10/memory-fragmentation
Marius Gedminas
2
@MariusGedminas tautan tidak berfungsi lagi karena itu penting untuk memberikan ringkasan singkat bersama tautan atau menjawab pertanyaan dengan ringkasan dengan tautan
katta
Tentu tapi sudah lebih dari setengah dekade
rsethc
3
Di bawah ini adalah lokasi yang diperbarui untuk tautan yang diposting oleh Marius: pavlovdotnet.wordpress.com/2007/11/10/memory-fragmentation
TheGameiswar

Jawaban:

313

Bayangkan Anda memiliki memori bebas "besar" (32 byte):

----------------------------------
|                                |
----------------------------------

Sekarang, alokasikan sebagian (5 alokasi):

----------------------------------
|aaaabbccccccddeeee              |
----------------------------------

Sekarang, bebaskan empat alokasi pertama tetapi bukan yang kelima:

----------------------------------
|              eeee              |
----------------------------------

Sekarang, cobalah untuk mengalokasikan 16 byte. Ups, saya tidak bisa, meskipun ada hampir dua kali lipat gratis.

Pada sistem dengan memori virtual, fragmentasi kurang menjadi masalah daripada yang mungkin Anda pikirkan, karena alokasi besar hanya perlu berdekatan dalam ruang alamat virtual , bukan dalam ruang alamat fisik . Jadi dalam contoh saya, jika saya memiliki memori virtual dengan ukuran halaman 2 byte maka saya dapat membuat alokasi 16 byte saya tanpa masalah. Memori fisik akan terlihat seperti ini:

----------------------------------
|ffffffffffffffeeeeff            |
----------------------------------

sedangkan memori virtual (menjadi jauh lebih besar) dapat terlihat seperti ini:

------------------------------------------------------...
|              eeeeffffffffffffffff                   
------------------------------------------------------...

Gejala klasik dari fragmentasi memori adalah Anda mencoba mengalokasikan blok besar dan Anda tidak bisa, walaupun Anda tampaknya memiliki cukup memori yang bebas. Konsekuensi lain yang mungkin adalah ketidakmampuan proses untuk melepaskan memori kembali ke OS (karena ada beberapa objek yang masih digunakan di semua blok yang telah dialokasikan dari OS, meskipun blok-blok itu sekarang sebagian besar tidak digunakan).

Taktik untuk mencegah fragmentasi memori dalam C ++ bekerja dengan mengalokasikan objek dari area yang berbeda sesuai dengan ukuran dan / atau umur yang diharapkan. Jadi jika Anda akan membuat banyak objek dan menghancurkannya bersama-sama nanti, alokasikan dari memori pool. Alokasi lain yang Anda lakukan di antara mereka tidak akan berasal dari kolam, karenanya tidak akan berada di antara mereka dalam memori, sehingga memori tidak akan terfragmentasi sebagai hasilnya.

Secara umum Anda tidak perlu terlalu khawatir tentang hal itu, kecuali jika program Anda berjalan lama dan melakukan banyak alokasi dan pembebasan. Saat Anda memiliki campuran benda yang berumur pendek dan berumur panjang, Anda paling berisiko, tetapi bahkan saat itumalloc akan melakukan yang terbaik untuk membantu. Pada dasarnya, abaikan saja sampai program Anda mengalami kegagalan alokasi atau secara tak terduga menyebabkan sistem kehabisan memori (lihat ini dalam pengujian, untuk preferensi!).

Perpustakaan standar tidak lebih buruk dari apa pun yang mengalokasikan memori, dan kontainer standar semua memiliki Allocparameter template yang dapat Anda gunakan untuk menyempurnakan strategi alokasi mereka jika benar-benar diperlukan.

Steve Jessop
sumber
1
Jadi setiap karakter adalah byte? Yang akan membuat "bentangan besar" == 32 byte (saya menduga - tidak masuk hitungan) :) Contoh yang bagus, tetapi menyebutkan unit sebelum baris terakhir akan sangat membantu. :)
jalf
1
@jalf: Yap. Saya tidak akan menyebutkan unit sama sekali, kemudian menyadari pada akhirnya saya harus. Sedang mengerjakannya saat Anda berkomentar.
Steve Jessop
Cukup sulit untuk memilih "jawaban" - banyak jawaban hebat di sini dan saya mendorong semua orang yang tertarik untuk membaca semuanya. Tetap saja, saya pikir Anda sudah membahas semua poin penting di sini.
AshleysBrain
1
"Perpustakaan standar tidak lebih buruk dari apa pun yang mengalokasikan memori". Itu akan bagus jika benar, tetapi implementasi template C ++ standar seperti string & vektor dapat memiliki beberapa perilaku yang sangat tidak diinginkan ketika mereka mengubah ukuran. Sebagai contoh dalam versi yang lebih lama dari studio visual string std :: pada dasarnya mengubah ukuran dengan realloc 1.5 * current_size (ke 8 byte terdekat). Jadi, jika Anda terus menambahkan string, Anda dapat meredam tumpukan dengan sangat mudah, terutama pada sistem embedded. Pertahanan terbaik adalah mencadangkan jumlah ruang yang Anda antisipasi gunakan untuk menghindari reallocs tersembunyi.
locka
1
@ du369: Memori virtual tidak terfragmentasi sama buruknya dengan fisiknya. ffffffffffffffffadalah alokasi yang berdekatan dalam memori virtual, tetapi tidak ada alokasi yang berdekatan seperti itu yang dapat ada dalam memori fisik. Jika Anda lebih suka melihatnya sama-sama terfragmentasi, tetapi ruang virtual jauh lebih besar, maka jangan ragu untuk melihatnya dengan cara itu. Poin praktis yang penting adalah bahwa menggunakan ruang alamat virtual yang luas seringkali cukup untuk dapat mengabaikan fragmentasi, sehingga membantu kapan pun memungkinkan saya untuk membuat alokasi 16 byte saya.
Steve Jessop
74

Apa itu fragmentasi memori?

Fragmentasi memori adalah ketika sebagian besar memori Anda dialokasikan dalam sejumlah besar blok yang tidak bersebelahan, atau potongan - membuat persentase yang baik dari total memori Anda tidak teralokasi, tetapi tidak dapat digunakan untuk sebagian besar skenario umum. Ini menghasilkan pengecualian dari kehabisan memori, atau kesalahan alokasi (yaitu malloc mengembalikan nol).

Cara termudah untuk memikirkan hal ini adalah membayangkan Anda memiliki dinding kosong besar yang Anda perlukan untuk meletakkan gambar dengan ukuran yang bervariasi . Setiap gambar mengambil ukuran tertentu dan Anda jelas tidak bisa membaginya menjadi potongan-potongan kecil agar pas. Anda memerlukan tempat kosong di dinding, ukuran gambar, atau Anda tidak bisa memasangnya. Sekarang, jika Anda mulai menggantung gambar di dinding dan Anda tidak berhati-hati tentang bagaimana Anda mengaturnya, Anda akan segera berakhir dengan dinding yang sebagian ditutupi dengan gambar dan meskipun Anda mungkin memiliki bintik-bintik kosong, sebagian besar gambar baru tidak akan cocok karena lebih besar dari tempat yang tersedia. Anda masih dapat menggantung gambar yang sangat kecil, tetapi sebagian besar tidak muat. Jadi, Anda harus mengatur ulang (kompak) yang sudah ada di dinding untuk memberikan ruang bagi lebih banyak ..

Sekarang, bayangkan dinding itu adalah memori (tumpukan) Anda dan gambar-gambar itu adalah objek .. Itu adalah fragmentasi memori ..

Bagaimana saya bisa tahu jika fragmentasi memori merupakan masalah bagi aplikasi saya? Program apa yang paling mungkin diderita?

Tanda bahwa Anda mungkin berurusan dengan fragmentasi memori adalah jika Anda mendapatkan banyak kesalahan alokasi, terutama ketika persentase memori yang digunakan tinggi - tetapi belum Anda belum menggunakan semua memori - jadi secara teknis Anda harus memiliki banyak ruang untuk objek yang Anda coba alokasikan.

Ketika memori sangat terfragmentasi, alokasi memori kemungkinan akan memakan waktu lebih lama karena pengalokasi memori harus melakukan lebih banyak pekerjaan untuk menemukan ruang yang cocok untuk objek baru. Jika pada gilirannya Anda memiliki banyak alokasi memori (yang mungkin Anda lakukan sejak Anda berakhir dengan fragmentasi memori) waktu alokasi bahkan dapat menyebabkan penundaan yang nyata.

Apa cara umum yang baik untuk menangani fragmentasi memori?

Gunakan algoritma yang baik untuk mengalokasikan memori. Alih-alih mengalokasikan memori untuk banyak objek kecil, pra-alokasikan memori untuk array yang berdekatan dari objek-objek kecil. Kadang-kadang menjadi sedikit boros ketika mengalokasikan memori dapat berjalan seiring untuk kinerja dan dapat menyelamatkan Anda kesulitan karena harus berurusan dengan fragmentasi memori.

Mike Dinescu
sumber
10
+1. Saya baru saja menghapus jawaban yang saya usulkan karena metafora "gambar di dinding" Anda benar-benar bagus, jelas.
ctacke
Saya lebih suka jika Anda menekankan fakta bahwa gambar harus memiliki ukuran yang bervariasi. Kalau tidak, tidak akan terjadi fragmentasi.
Björn Pollex
1
Menariknya, basis data memori utama menjadi agak praktis akhir-akhir ini (dengan sangat banyak memori yang tersedia). Dalam konteks ini perlu dicatat bahwa, seperti untuk HDD, membaca garis kontinu dari RAM jauh lebih cepat daripada jika data terfragmentasi.
Björn Pollex
1
Analogi visual yang bagus dengan gambar-gambar di dinding, tetapi memori utama bukan dua dimensi! Tetap saja, jawaban yang bagus, terima kasih.
AshleysBrain
24

Memori fragmentasi adalah konsep yang sama dengan disk fragmentasi: ini mengacu pada ruang yang terbuang karena area yang digunakan tidak cukup berdekatan.

Misalkan untuk contoh mainan sederhana bahwa Anda memiliki sepuluh byte memori:

 |   |   |   |   |   |   |   |   |   |   |
   0   1   2   3   4   5   6   7   8   9

Sekarang mari kita alokasikan tiga blok tiga byte, nama A, B, dan C:

 | A | A | A | B | B | B | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9

Sekarang alokasikan blok B:

 | A | A | A |   |   |   | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9

Sekarang apa yang terjadi jika kita mencoba mengalokasikan empat byte blok D? Yah, kami memiliki empat byte memori bebas, tetapi kami tidak memiliki empat byte memori yang berdekatan , jadi kami tidak dapat mengalokasikan D! Ini adalah penggunaan memori yang tidak efisien, karena kita seharusnya dapat menyimpan D, tetapi kami tidak dapat melakukannya. Dan kami tidak dapat memindahkan C untuk memberi ruang, karena sangat mungkin beberapa variabel dalam program kami menunjuk ke C, dan kami tidak dapat secara otomatis menemukan dan mengubah semua nilai-nilai ini.

Bagaimana Anda tahu itu masalah? Nah, pertanda terbesar adalah bahwa ukuran memori virtual program Anda jauh lebih besar daripada jumlah memori yang sebenarnya Anda gunakan. Dalam contoh dunia nyata, Anda akan memiliki lebih dari sepuluh byte memori, jadi D hanya akan dialokasikan mulai byte 9, dan byte 3-5 akan tetap tidak digunakan kecuali Anda nanti mengalokasikan sesuatu yang panjangnya tiga byte atau lebih kecil.

Dalam contoh ini, 3 byte tidak terlalu banyak untuk diboroskan, tetapi pertimbangkan kasus yang lebih patologis di mana dua alokasi beberapa byte, misalnya, terpisah sepuluh megabyte dalam memori, dan Anda perlu mengalokasikan blok ukuran 10 megabyte +1 byte Anda harus meminta OS untuk lebih dari sepuluh megabyte lebih banyak memori virtual untuk melakukan itu, meskipun Anda hanya satu byte malu sudah memiliki cukup ruang.

Bagaimana Anda mencegahnya? Kasus terburuk cenderung muncul ketika Anda sering membuat dan menghancurkan benda-benda kecil, karena itu cenderung menghasilkan efek "keju swiss" dengan banyak benda kecil yang dipisahkan oleh banyak lubang kecil, sehingga tidak mungkin mengalokasikan benda yang lebih besar di lubang-lubang itu. Ketika Anda tahu Anda akan melakukan ini, strategi yang efektif adalah dengan pra-alokasi blok memori besar sebagai kumpulan untuk objek kecil Anda, dan kemudian secara manual mengelola pembuatan objek kecil di dalam blok itu, daripada membiarkan pengalokasi default menanganinya.

Secara umum, semakin sedikit alokasi yang Anda lakukan, semakin kecil kemungkinan memori terfragmentasi. Namun, STL menangani hal ini dengan cukup efektif. Jika Anda memiliki string yang menggunakan keseluruhan dari alokasi saat ini dan Anda menambahkan satu karakter untuk itu, itu tidak hanya mengalokasikan kembali ke panjang saat ini ditambah satu, itu menggandakan panjangnya. Ini adalah variasi pada strategi "kumpulan untuk alokasi kecil yang sering". Tali mengambil sebagian besar memori sehingga dapat menangani secara efisien dengan peningkatan ukuran kecil berulang tanpa melakukan realokasi kecil berulang. Semua wadah STL sebenarnya melakukan hal semacam ini, jadi umumnya Anda tidak perlu terlalu khawatir tentang fragmentasi yang disebabkan oleh realokasi ulang wadah STL.

Meskipun tentu saja wadah STL tidak menyatukan memori antara satu sama lain, jadi jika Anda akan membuat banyak wadah kecil (daripada beberapa wadah yang sering diubah ukurannya), Anda mungkin harus khawatir dengan mencegah fragmentasi dengan cara yang sama seperti Anda. akan untuk benda kecil yang sering dibuat, STL atau tidak.

Tyler McHenry
sumber
14
  • Apa itu fragmentasi memori?

Fragmentasi memori adalah masalah memori menjadi tidak dapat digunakan meskipun secara teoritis tersedia. Ada dua jenis fragmentasi: fragmentasi internal adalah memori yang dialokasikan tetapi tidak dapat digunakan (misalnya ketika memori dialokasikan dalam potongan 8 byte tetapi program berulang kali melakukan alikasi tunggal ketika hanya membutuhkan 4 byte). fragmentasi eksternal adalah masalah memori bebas yang dibagi menjadi banyak potongan kecil sehingga permintaan alokasi yang besar tidak dapat dipenuhi meskipun ada cukup memori bebas secara keseluruhan.

  • Bagaimana saya bisa tahu jika fragmentasi memori merupakan masalah bagi aplikasi saya? Program apa yang paling mungkin diderita?

fragmentasi memori adalah masalah jika program Anda menggunakan lebih banyak memori sistem daripada data paylod yang sebenarnya diperlukan (dan Anda telah mengesampingkan kebocoran memori).

  • Apa cara umum yang baik untuk menangani fragmentasi memori?

Gunakan pengalokasi memori yang baik. IIRC, mereka yang menggunakan strategi "paling cocok" umumnya jauh lebih unggul dalam menghindari fragmentasi, jika sedikit lebih lambat. Namun, juga telah ditunjukkan bahwa untuk strategi alokasi apa pun, ada kasus terburuk yang bersifat patologis. Untungnya, pola alokasi khas sebagian besar aplikasi sebenarnya relatif jinak untuk ditangani oleh pengalokasi. Ada banyak makalah di luar sana jika Anda tertarik dengan detailnya:

  • Paul R. Wilson, Mark S. Johnstone, Michael Neely dan David Boles. Alokasi Penyimpanan Dinamis: Survei dan Tinjauan Kritis. Dalam Prosiding Lokakarya Internasional 1995 tentang Manajemen Memori, Springer Verlag LNCS, 1995
  • Mark S.Johnstone, Paul R. Wilson. Masalah Fragmentasi Memori: Dipecahkan? Dalam ACM SIG-PLAN Notices, volume 34 No. 3, halaman 26-36, 1999
  • MR Garey, RL Graham dan JD Ullman. Analisis algoritma alokasi memori terburuk. Dalam Simposium ACM Tahunan Keempat tentang Teori Komputasi, 1972
Michael Borgwardt
sumber
9

Pembaruan:
Google TCMalloc: Thread-Caching Malloc
Telah ditemukan bahwa ia cukup bagus dalam menangani fragmentasi dalam proses yang berjalan lama.


Saya telah mengembangkan aplikasi server yang memiliki masalah dengan fragmentasi memori pada HP-UX 11.23 / 11.31 ia64.

Terlihat seperti ini. Ada proses yang membuat alokasi memori dan alokasi dan berjalan selama berhari-hari. Dan meskipun tidak ada kebocoran memori, konsumsi memori dari proses terus meningkat.

Tentang pengalaman saya. Pada HP-UX sangat mudah untuk menemukan fragmentasi memori menggunakan HP-UX gdb. Anda mengatur break-point dan ketika Anda menekannya Anda menjalankan perintah ini: info heapdan melihat semua alokasi memori untuk proses dan ukuran total tumpukan. Kemudian Anda melanjutkan program Anda dan kemudian beberapa waktu kemudian Anda lagi mencapai break-point. Anda lakukan lagi info heap. Jika ukuran total tumpukan lebih besar tetapi jumlah dan ukuran alokasi terpisah adalah sama, maka kemungkinan Anda memiliki masalah alokasi memori. Jika perlu lakukan ini periksa beberapa kali sebelumnya.

Cara saya memperbaiki situasi adalah ini. Setelah saya melakukan beberapa analisis dengan HP-UX gdb saya melihat bahwa masalah memori disebabkan oleh kenyataan bahwa saya menggunakan std::vectoruntuk menyimpan beberapa jenis informasi dari database. std::vectormensyaratkan bahwa datanya harus disimpan dalam satu blok. Saya memiliki beberapa wadah berdasarkan std::vector. Wadah-wadah ini secara teratur diciptakan kembali. Sering ada situasi ketika catatan baru ditambahkan ke database dan setelah itu wadah dibuat kembali. Dan karena kontainer yang dibuat ulang berukuran lebih besar, maka tidak sesuai dengan blok memori bebas yang tersedia dan runtime meminta blok baru yang lebih besar dari OS. Akibatnya meskipun tidak ada kebocoran memori konsumsi memori proses tumbuh. Saya memperbaiki situasi ketika saya mengganti wadah. Dari padastd::vector saya mulai menggunakanstd::deque yang memiliki cara berbeda mengalokasikan memori untuk data.

Saya tahu bahwa salah satu cara untuk menghindari fragmentasi memori pada HP-UX adalah dengan menggunakan Small Block Allocator atau menggunakan MallocNextGen. Pada RedHat Linux, pengalokasi default tampaknya menangani pengalokasian banyak blok kecil dengan cukup baik. Pada Windows ada Low-fragmentation Heapdan mengatasi masalah sejumlah besar alokasi kecil.

Pemahaman saya adalah bahwa dalam aplikasi STL-berat Anda harus terlebih dahulu mengidentifikasi masalah. Alokasi memori (seperti dalam libc) sebenarnya menangani masalah banyak alokasi kecil, yang tipikal untuk std::string(misalnya dalam aplikasi server saya ada banyak string STL tetapi seperti yang saya lihat dari menjalankan info heapmereka tidak menyebabkan masalah). Kesan saya adalah Anda harus menghindari alokasi besar yang sering. Sayangnya ada situasi ketika Anda tidak dapat menghindarinya dan harus mengubah kode Anda. Seperti yang saya katakan dalam kasus saya, saya memperbaiki situasi ketika beralih ke std::deque. Jika Anda mengidentifikasi fragmen memori Anda, mungkin untuk membicarakannya lebih tepat.


sumber
6

Memori fragmentasi paling mungkin terjadi ketika Anda mengalokasikan dan membatalkan alokasi banyak objek dari berbagai ukuran. Misalkan Anda memiliki tata letak berikut dalam memori:

obj1 (10kb) | obj2(20kb) | obj3(5kb) | unused space (100kb)

Sekarang, ketika obj2dirilis, Anda memiliki 120kb memori yang tidak digunakan, tetapi Anda tidak dapat mengalokasikan blok penuh 120kb, karena memori terfragmentasi.

Teknik umum untuk menghindari efek itu termasuk buffer cincin dan kolam objek . Dalam konteks STL, metode seperti std::vector::reserve()dapat membantu.

Björn Pollex
sumber
3

Apa itu fragmentasi memori?

Saat aplikasi Anda menggunakan memori dinamis, itu mengalokasikan dan membebaskan potongan memori. Pada awalnya, seluruh ruang memori aplikasi Anda adalah satu blok memori bebas yang bersebelahan. Namun, ketika Anda mengalokasikan dan membebaskan blok dari ukuran yang berbeda, memori mulai menjadi terfragmentasi , yaitu alih-alih blok bebas berdekatan yang besar dan sejumlah blok yang dialokasikan berdekatan, akan ada blok yang dialokasikan dan blok bebas bercampur. Karena blok gratis memiliki ukuran terbatas, sulit untuk menggunakannya kembali. Misalnya Anda mungkin memiliki 1000 byte memori bebas, tetapi tidak dapat mengalokasikan memori untuk blok 100 byte, karena semua blok bebas paling panjangnya 50 byte.

Sumber fragmentasi lain yang tak terhindarkan, tetapi tidak terlalu bermasalah adalah bahwa di sebagian besar arsitektur, alamat memori harus disejajarkan dengan batas byte 2, 4, 8 dll. (Yaitu alamat harus kelipatan 2, 4, 8 dll.) Ini berarti bahwa bahkan jika Anda memiliki mis sebuah struct yang berisi 3 charbidang, struct Anda mungkin memiliki ukuran 12 bukannya 3, karena fakta bahwa setiap bidang disejajarkan dengan batas 4-byte.

Bagaimana saya bisa tahu jika fragmentasi memori merupakan masalah bagi aplikasi saya? Program apa yang paling mungkin diderita?

Jawaban yang jelas adalah bahwa Anda mendapatkan pengecualian memori.

Tampaknya tidak ada cara portabel yang baik untuk mendeteksi fragmentasi memori di aplikasi C ++. Lihat jawaban ini untuk lebih jelasnya.

Apa cara umum yang baik untuk menangani fragmentasi memori?

Sulit di C ++, karena Anda menggunakan alamat memori langsung dalam pointer, dan Anda tidak memiliki kendali atas siapa yang merujuk alamat memori tertentu. Jadi menata ulang blok memori yang dialokasikan (cara pengumpul sampah Java) bukanlah suatu pilihan.

Alokasi kustom dapat membantu dengan mengelola alokasi objek kecil di memori yang lebih besar, dan menggunakan kembali slot gratis di dalam chunk itu.

Péter Török
sumber
3

Ini adalah versi super disederhanakan untuk boneka.

Saat objek dibuat dalam memori, mereka bisa ditambahkan ke akhir bagian yang digunakan dalam memori.

Jika sebuah objek yang tidak berada di bagian akhir dari memori yang digunakan dihapus, artinya objek ini berada di antara 2 objek lain, itu akan membuat "lubang".

Inilah yang disebut fragmentasi.

pengguna455288
sumber
2

Ketika Anda ingin menambahkan item pada heap, yang terjadi adalah komputer harus mencari ruang yang cocok dengan item itu. Itu sebabnya alokasi dinamis ketika tidak dilakukan pada memori pool atau dengan alokasi pooling dapat "memperlambat" segalanya. Untuk aplikasi STL yang berat jika Anda melakukan multi-threading ada Hoard alokasi atau versi Intel TBB .

Sekarang, ketika memori terfragmentasi, dua hal dapat terjadi:

  1. Harus ada lebih banyak pencarian untuk menemukan ruang yang baik untuk menempel objek "besar". Yaitu, dengan banyak benda kecil berserakan menemukan sepotong memori bagus yang bagus dalam kondisi tertentu menjadi sulit (ini ekstrem.)
  2. Memori bukanlah entitas yang mudah dibaca. Prosesor terbatas pada seberapa banyak yang dapat mereka pegang dan di mana. Mereka melakukan ini dengan menukar halaman jika item yang mereka butuhkan adalah satu tempat tetapi alamat saat ini adalah yang lain. Jika Anda terus-menerus harus menukar halaman, pemrosesan dapat melambat (lagi, skenario ekstrem di mana ini berdampak pada kinerja.) Lihat posting ini di memori virtual .
wheaties
sumber
1

Fragmentasi memori terjadi karena blok memori dengan ukuran berbeda diminta. Pertimbangkan buffer 100 byte. Anda meminta dua karakter, lalu bilangan bulat. Sekarang Anda membebaskan dua karakter, lalu meminta bilangan bulat baru - tetapi bilangan bulat itu tidak bisa masuk dalam ruang dua karakter tersebut. Memori itu tidak dapat digunakan kembali karena tidak dalam blok berdekatan yang cukup besar untuk dialokasikan kembali. Selain itu, Anda telah meminta banyak overhead pengalokasi untuk karakter Anda.

Pada dasarnya, memori hanya datang dalam ukuran tertentu pada sebagian besar sistem. Setelah Anda membagi blok-blok ini, mereka tidak dapat digabungkan kembali sampai seluruh blok dibebaskan. Ini dapat menyebabkan seluruh blok digunakan ketika sebenarnya hanya sebagian kecil dari blok yang digunakan.

Cara utama untuk mengurangi fragmentasi timbunan adalah dengan membuat alokasi yang lebih besar dan lebih jarang. Secara ekstrem, Anda dapat menggunakan tumpukan yang dikelola yang mampu memindahkan objek, setidaknya, dalam kode Anda sendiri. Ini benar-benar menghilangkan masalah - dari perspektif memori, sih. Jelas benda yang bergerak dan semacamnya memiliki biaya. Pada kenyataannya, Anda hanya benar-benar memiliki masalah jika Anda sering mengalokasikan jumlah yang sangat kecil dari tumpukan. Menggunakan wadah yang berdekatan (vektor, tali, dll) dan mengalokasikan pada tumpukan sebanyak mungkin secara manusiawi (selalu merupakan ide bagus untuk kinerja) adalah cara terbaik untuk menguranginya. Ini juga meningkatkan koherensi cache, yang membuat aplikasi Anda berjalan lebih cepat.

Yang harus Anda ingat adalah bahwa pada sistem desktop 32bit x86, Anda memiliki seluruh memori 2GB, yang dipecah menjadi "halaman" 4KB (cukup yakin ukuran halaman sama pada semua sistem x86). Anda harus memanggil beberapa fragmentasi omgwtfbbq untuk memiliki masalah. Fragmentasi benar-benar merupakan masalah masa lalu, karena tumpukan modern terlalu besar untuk sebagian besar aplikasi, dan ada prevalensi sistem yang mampu menahannya, seperti tumpukan yang dikelola.

Anak anjing
sumber
0

Program apa yang paling mungkin diderita?

Contoh bagus (= mengerikan) untuk masalah yang terkait dengan fragmentasi memori adalah pengembangan dan pelepasan "Elemental: War of Magic" , sebuah game komputer oleh Stardock .

Permainan ini dibangun untuk Memori 32bit / 2GB dan harus melakukan banyak optimasi dalam manajemen memori untuk membuat permainan bekerja di dalam Memori 2GB tersebut. Karena "optimisasi" mengarah ke alokasi dan de-alokasi yang konstan, dari waktu ke waktu tumpukan fragmentasi memori terjadi dan membuat game mogok setiap saat .

Ada wawancara "kisah perang" di YouTube.

Thomas
sumber