Dalam banyak buku dan tutorial, saya've mendengar praktek manajemen memori stres dan merasa bahwa beberapa misterius dan hal-hal buruk akan terjadi jika saya tidak't memori bebas setelah aku'm dilakukan dengan menggunakan itu.
Saya dapat't berbicara untuk sistem lain (meskipun bagi saya itu's yang wajar untuk menganggap bahwa mereka mengadopsi praktek yang serupa), tapi setidaknya pada Windows, Kernel pada dasarnya adalah dijamin untuk pembersihan sebagian besar sumber daya (dengan pengecualian beberapa hal) yang digunakan oleh program setelah program penghentian. Yang meliputi memori tumpukan, di antara berbagai hal lainnya.
Saya mengerti mengapa anda akan ingin untuk menutup file setelah anda're dilakukan dengan menggunakan itu dalam rangka untuk membuatnya tersedia untuk pengguna atau mengapa anda akan ingin untuk memutuskan sambungan soket yang terhubung ke server dalam rangka untuk menghemat bandwidth, tapi tampaknya konyol untuk memiliki untuk micromanage SEMUA memori yang digunakan oleh program anda.
Sekarang, saya setuju bahwa pertanyaan ini lebih luas karena bagaimana anda harus menangani memori anda didasarkan pada seberapa banyak memori yang anda butuhkan dan ketika anda membutuhkannya, jadi saya akan mempersempit ruang lingkup pertanyaan ini: Jika saya harus menggunakan sepotong memori sepanjang umur dari program saya, itu benar-benar diperlukan untuk gratis itu tepat sebelum program penghentian?
Edit: Pertanyaan yang disarankan sebagai duplikat itu khusus untuk keluarga sistem operasi Unix. Atas jawaban bahkan ditentukan alat khusus untuk Linux (misalnya Valgrind). Pertanyaan ini dimaksudkan untuk menutupi sebagian besar "normal" non-embedded sistem operasi dan mengapa atau isn't praktik yang baik untuk memori bebas yang diperlukan sepanjang umur dari suatu program.
Jika saya harus menggunakan sepotong memori sepanjang umur dari program saya, itu benar-benar diperlukan untuk gratis itu tepat sebelum program penghentian?
Hal ini tidak wajib, tetapi dapat memiliki manfaat (serta beberapa kelemahan).
Jika program mengalokasikan memori sekali selama waktu pelaksanaannya, dan sebaliknya akan pernah melepaskannya sampai proses berakhir, mungkin pendekatan yang masuk akal untuk tidak membebaskan memori secara manual dan mengandalkan OS. Pada setiap OS modern yang saya tahu, ini adalah aman, pada akhir dari semua proses dialokasikan di memori andal kembali ke sistem. Dalam beberapa kasus, tidak membersihkan memori yang dialokasikan secara eksplisit bahkan mungkin terutama lebih cepat daripada melakukan bersih-bersih.
Namun, dengan melepaskan semua memori di akhir eksekusi secara eksplisit,
Umur dari program-program yang dapat mengubah. Mungkin anda program adalah utilitas baris perintah saat ini, dengan ciri khas seumur hidup kurang dari 10 menit, dan itu mengalokasikan memori di bagian-bagian dari beberapa kb setiap 10 detik - sehingga tidak perlu untuk membebaskan setiap memori yang dialokasikan di semua sebelum program ini berakhir. Kemudian pada program ini berubah dan akan diperpanjang penggunaan sebagai bagian dari proses server dengan seumur hidup beberapa minggu - agar tidak membebaskan memori yang tidak terpakai di antara adalah bukan sebuah pilihan lagi, jika program anda mulai makan sampai semua tersedia memori server dari waktu ke waktu. Ini berarti anda akan memiliki untuk meninjau seluruh program dan tambahkan deallocating kode sesudahnya. Jika anda beruntung, ini adalah tugas yang mudah, jika tidak, mungkin begitu keras bahwa kemungkinan besar anda melewatkan tempat. Dan ketika anda berada dalam situasi itu, anda akan berharap anda telah ditambahkan "gratis" kode program anda terlebih dahulu, pada saat anda menambahkan "malloc" kode.
Lebih umumnya, menulis mengalokasikan dan terkait deallocating kode selalu berpasangan dianggap sebagai "kebiasaan yang baik" di antara banyak programmer: dengan melakukan ini, anda mengurangi kemungkinan melupakan deallocation kode dalam situasi di mana memori harus dibebaskan.
Membebaskan memori pada akhir dari program yang dijalankan hanya membuang-buang waktu CPU. It's seperti merapikan rumah sebelum menghancurkannya dari orbit.
Namun kadang-kadang apa yang telah menjalankan program dapat berubah menjadi bagian dari banyak lagi berjalan satu. Kemudian membebaskan hal-hal menjadi perlu. Jika ini tidak't berpikir tentang untuk setidaknya batas tertentu maka dapat melibatkan substansial pengerjaan ulang.
Salah satu solusi cerdas untuk ini adalah "talloc" yang memungkinkan anda membuat beban alokasi memori dan kemudian melemparkan mereka semua pergi dengan satu panggilan.
Anda bisa menggunakan bahasa dengan pengumpulan sampah (seperti Skema, Ocaml, Haskell, Common Lisp, dan bahkan Java, Scala, Clojure).
(Di paling GC-ed bahasa, tidak ada cara untuk secara eksplisit dan manual free memori! Kadang-kadang, beberapa nilai-nilai yang mungkin diselesaikan, misalnya GC dan runtime system akan menutup file handle nilai saat yang tidak terjangkau, tetapi hal ini tidak pasti, tidak dapat diandalkan, dan anda malah harus tutup secara eksplisit anda menangani file, sejak finalisasi tidak pernah dijamin)
Anda juga bisa, untuk program anda dikodekan dalam C (atau C++) menggunakan Boehm's konservatif garbage collector. Anda kemudian akan mengganti semua malloc
dengan GC_malloc
dan tidak repot-repot tentang gratis
-ing setiap pointer. Tentu saja anda perlu untuk memahami lebih baik dan conses menggunakan Boehm's GC. Baca juga GC handbook.
manajemen Memori adalah properti global dari suatu program. Dalam beberapa cara itu (dan liveness diberikan beberapa data) adalah non-komposisi dan non-modular, karena seluruh program properti.
Pada akhirnya, seperti orang-orang lain menunjukkan, secara eksplisit gratis
-ing anda tumpukan dialokasikan C memory zone adalah praktik yang baik. Untuk mainan program tidak mengalokasikan banyak memori, anda bahkan bisa memutuskan untuk tidak gratis
memori pada semua (sejak kapan proses telah berakhir, sumber daya, termasuk ruang alamat virtual, akan dibebaskan oleh sistem operasi).
Jika saya harus menggunakan sepotong memori sepanjang umur dari program saya, itu benar-benar diperlukan untuk gratis itu tepat sebelum program penghentian?
Tidak, anda don't perlu melakukan itu. Dan banyak dunia nyata program don't repot-repot membebaskan beberapa memori yang dibutuhkan pada seluruh umur (khususnya GCC compiler tidak membebaskan beberapa memori). Namun, ketika anda melakukan itu (misalnya anda don't repot-repot gratis
-ing beberapa bagian tertentu dari C dialokasikan secara dinamis data), anda'll lebih baik komentar fakta bahwa meringankan pekerjaan masa depan programmer pada proyek yang sama. Saya cenderung untuk merekomendasikan bahwa jumlah unfreed memori tetap dibatasi, dan biasanya relatif kecil w.r.t. untuk total yang digunakan heap memory.
Perhatikan bahwa sistem gratis
sering tidak melepaskan memori dengan OS (misalnya dengan memanggil munmap(2) pada sistem POSIX) tapi biasanya menandai zona memori sebagai dapat digunakan oleh masa depan malloc
. Secara khusus, ruang alamat virtual (misalnya seperti yang terlihat melalui /proc/self/maps
di Linux, lihat proc(5)....) mungkin tidak menyusut setelah bebas
(maka utilitas seperti ps
atau atas
melaporkan jumlah yang sama dari memori yang digunakan untuk proses anda).
Hal ini tidak diperlukan, seperti dalam anda tidak akan gagal untuk mengeksekusi program anda dengan benar jika anda gagal untuk. Namun, ada alasan-alasan yang dapat anda pilih, jika diberi kesempatan.
Salah satu yang paling kuat kasus saya lari ke (berulang) adalah bahwa seseorang menulis sepotong kecil dari simulasi kode yang berjalan di eksekusi. Mereka mengatakan "kami'd seperti kode ini untuk diintegrasikan ke dalam simulasi." saya kemudian meminta mereka bagaimana mereka berencana untuk kembali menginisialisasi antara monte-carlo berjalan, dan mereka melihat saya dengan pandangan yang kosong. "Apa maksudmu re-initialize? Anda hanya menjalankan program dengan pengaturan baru?"
Kadang-kadang bersih pembersihan membuatnya banyak lebih mudah untuk anda perangkat lunak yang akan digunakan. Dalam kasus banyak contoh, anda kira anda tidak perlu untuk membersihkan sesuatu, dan anda membuat asumsi tentang bagaimana anda dapat menangani data dan umur nya sekitar mereka praduga. Ketika anda pindah ke sebuah lingkungan baru di mana orang-orang praduga tidak berlaku, seluruh algoritma yang mungkin tidak lagi bekerja.
Untuk contoh betapa hal-hal aneh bisa mendapatkan, melihat bagaimana dikelola bahasa berurusan dengan finalisasi pada akhir proses, atau bagaimana C# berkaitan dengan program menghentikan Aplikasi Domain. Mereka mengikat diri dalam knot karena ada's asumsi-asumsi yang jatuh melalui celah-celah dalam kasus-kasus ekstrim.
Mengabaikan bahasa di mana anda don't memori secara manual sih...
Apa yang anda pikirkan sebagai "program" sekarang mungkin di beberapa titik menjadi sebuah fungsi atau metode yang merupakan bagian dari program yang lebih besar. Dan kemudian fungsi itu mungkin bisa disebut beberapa kali. Dan kemudian memori yang anda harus memiliki "freed manual" akan kebocoran memori. Yang tentu saja keputusan.
Tidak, itu tidak perlu, tapi itu's merupakan Ide yang Baik.
Anda mengatakan anda merasa bahwa "misterius dan hal-hal buruk akan terjadi jika saya tidak't memori bebas setelah aku'm dilakukan dengan menggunakan itu."
Dalam istilah teknis, hanya konsekuensi dari ini adalah bahwa program anda akan terus makan lebih banyak memori sampai baik sepanjang batas tersebut tercapai (misalnya ruang alamat virtual habis) atau kinerja menjadi tidak dapat diterima. Jika program adalah tentang untuk keluar, tidak satupun dari hal ini penting karena proses yang efektif berhenti untuk eksis. "misterius dan hal-hal buruk" adalah murni tentang pengembang's keadaan mental. Menemukan sumber kebocoran memori dapat menjadi mimpi buruk absolut (ini adalah meremehkan) dan dibutuhkan banyak keterampilan dan disiplin untuk menulis kode yang lebih bebas bocor. Pendekatan yang direkomendasikan untuk mengembangkan keterampilan dan disiplin selalu free memory setelah itu tidak lagi diperlukan, bahkan jika program ini akan berakhir.
Tentu saja hal ini memiliki keuntungan tambahan bahwa kode anda dapat digunakan kembali dan disesuaikan dengan lebih mudah, seperti yang dikatakan orang lain.
Namun, setidaknya ada satu kasus di mana itu lebih baik not untuk membebaskan memori sebelum program penghentian.
Pertimbangkan kasus di mana anda telah membuat jutaan alokasi kecil, dan mereka sebagian besar telah bertukar ke disk. Ketika anda mulai membebaskan semuanya, sebagian besar memori anda perlu untuk mendapatkan bertukar kembali ke dalam RAM sehingga pembukuan informasi yang dapat diakses, hanya untuk segera membuang data. Hal ini dapat membuat program memakan waktu beberapa menit saja untuk keluar! Belum lagi menempatkan banyak tekanan pada disk dan memori fisik selama waktu itu. Jika memori fisik dalam pasokan pendek untuk mulai dengan (mungkin program ini ditutup karena program lain adalah mengunyah banyak memori) maka halaman individu mungkin perlu di-swap masuk dan keluar beberapa kali ketika beberapa benda yang harus dibebaskan dari halaman yang sama, tetapi tidak dibebaskan berturut-turut.
Jika bukan program yang hanya dibatalkan, OS hanya akan membuang semua memori yang telah di-swap ke disk, yang hampir seketika karena itu doesn't memerlukan akses disk sama sekali.
It's penting untuk dicatat bahwa dalam sebuah OO bahasa, memanggil object's destructor juga akan memaksa memori untuk ditukarkan dalam; jika anda memiliki untuk melakukan ini, anda mungkin juga membebaskan memori.
Karena itu's sangat mungkin bahwa dalam beberapa waktu anda'll ingin mengubah program anda, mungkin mengintegrasikannya dengan sesuatu yang lain, menjalankan beberapa contoh dalam urutan atau paralel. Maka itu'll menjadi perlu untuk secara manual gratis memori ini - tapi anda tidak't akan mengingat keadaan lagi dan itu'll biaya anda lebih banyak waktu untuk kembali memahami program anda.
Melakukan hal-hal sementara pemahaman anda tentang mereka masih segar.
Alasan utama untuk membersihkan secara manual adalah: anda kurang kemungkinan untuk kesalahan yang asli kebocoran memori untuk sebuah blok memori yang hanya akan dibersihkan pada keluar, kadang-kadang anda akan menangkap bug di pengalokasi hanya ketika anda berjalan seluruh struktur data deallocate itu, dan anda akan memiliki waktu yang jauh lebih kecil sakit kepala jika anda pernah refactor sehingga beberapa objek tidak membutuhkan untuk mendapatkan deallocated sebelum keluar program.
Alasan utama untuk tidak membersihkan secara manual adalah: kinerja, kinerja, kinerja, dan kemungkinan beberapa jenis free-dua kali atau digunakan setelah bebas bug anda tidak perlu bersih-bersih kode, yang dapat berubah menjadi bug kecelakaan atau eksploitasi keamanan.
Jika anda peduli tentang kinerja, anda selalu ingin untuk profil untuk mencari tahu di mana kau menyia-nyiakan semua waktu anda, bukan menebak-nebak. Sebuah kompromi yang mungkin adalah untuk membungkus opsional bersih-up kode dalam blok bersyarat, meninggalkannya di saat debugging agar anda mendapatkan manfaat dari tulisan dan debugging kode, dan kemudian, jika dan hanya jika anda telah ditentukan secara empiris bahwa itu terlalu banyak overhead, memberitahu compiler untuk melewati itu di akhir eksekusi. Dan keterlambatan dalam penutupan program ini, hampir secara definisi, hampir tidak pernah di jalur kritis.