Apakah bisa diterima jika ada kebocoran memori di aplikasi C atau C ++ Anda?
Bagaimana jika Anda mengalokasikan sebagian memori dan menggunakannya hingga baris terakhir kode dalam aplikasi Anda (misalnya, destruktor objek global)? Selama konsumsi memori tidak tumbuh dari waktu ke waktu, apakah boleh mempercayai OS untuk membebaskan memori Anda ketika aplikasi Anda berakhir (pada Windows, Mac, dan Linux)? Apakah Anda bahkan menganggap ini sebagai kebocoran memori nyata jika memori sedang digunakan terus menerus sampai dibebaskan oleh OS.
Bagaimana jika perpustakaan pihak ketiga memaksakan situasi ini pada Anda? Apakah akan menolak untuk menggunakan perpustakaan pihak ketiga itu tidak peduli seberapa hebatnya itu?
Saya hanya melihat satu kelemahan praktis, dan itu adalah bahwa kebocoran jinak ini akan muncul dengan alat pendeteksi kebocoran memori sebagai positif palsu.
sumber
Jawaban:
Tidak.
Sebagai profesional, pertanyaan yang tidak seharusnya kita tanyakan pada diri kita sendiri adalah, "Apakah pernah boleh melakukan ini?" melainkan "Apakah ada alasan bagus untuk melakukan ini?" Dan "memburu kebocoran memori itu menyakitkan" bukanlah alasan yang bagus.
Saya suka menjaga hal-hal sederhana. Dan aturan sederhananya adalah bahwa program saya seharusnya tidak memiliki kebocoran memori.
Itu membuat hidup saya juga sederhana. Jika saya mendeteksi kebocoran memori, saya menghilangkannya, daripada menjalankan melalui struktur pohon keputusan yang rumit untuk menentukan apakah itu kebocoran memori yang "dapat diterima".
Ini mirip dengan peringatan kompiler - apakah peringatan itu berakibat fatal bagi aplikasi khusus saya? Mungkin tidak.
Tetapi pada akhirnya masalah disiplin profesional. Menoleransi peringatan kompiler dan mentoleransi kebocoran memori adalah kebiasaan buruk yang pada akhirnya akan menggigit saya di belakang.
Untuk mengambil hal-hal yang ekstrem, apakah akan dapat diterima bagi ahli bedah untuk meninggalkan beberapa peralatan operasi di dalam pasien?
Meskipun ada kemungkinan bahwa suatu keadaan dapat muncul di mana biaya / risiko mengeluarkan peralatan itu melebihi biaya / risiko meninggalkannya, dan mungkin ada keadaan di mana itu tidak berbahaya, jika saya melihat pertanyaan ini diposting di SurgeonOverflow.com dan melihat jawaban apa pun selain "tidak," itu akan merusak kepercayaan diri saya pada profesi medis.
-
Jika perpustakaan pihak ketiga memaksakan situasi ini pada saya, itu akan menuntun saya untuk secara serius mencurigai kualitas keseluruhan perpustakaan yang dimaksud. Seolah-olah saya menguji mengendarai mobil dan menemukan beberapa mesin cuci dan mur longgar di salah satu pemegang cangkir - itu mungkin bukan masalah besar dalam dirinya sendiri, tetapi itu menggambarkan kurangnya komitmen terhadap kualitas, jadi saya akan mempertimbangkan alternatif.
sumber
Saya tidak menganggapnya sebagai kebocoran memori kecuali jumlah memori yang "digunakan" terus bertambah. Memiliki beberapa memori yang belum dirilis, meskipun tidak ideal, bukanlah masalah besar kecuali jika jumlah memori yang dibutuhkan terus bertambah.
sumber
Mari kita buat definisi kita benar, pertama. Kebocoran memori adalah ketika memori dialokasikan secara dinamis, misalnya dengan
malloc()
, dan semua referensi ke memori hilang tanpa bebas yang sesuai. Cara mudah untuk membuatnya adalah seperti ini:Perhatikan bahwa setiap kali sekitar while (1) loop, 1024 (+ overhead) byte dialokasikan, dan alamat baru ditetapkan untuk vp; tidak ada pointer yang tersisa ke blok malloc'ed sebelumnya. Program ini dijamin berjalan hingga tumpukan habis, dan tidak ada cara untuk memulihkan memori malloc'ed. Memori "bocor" keluar dari tumpukan, tidak pernah terlihat lagi.
Seperti apa yang Anda gambarkan, terdengar
Anda mengalokasikan memori, bekerja dengannya sampai program berakhir. Ini bukan kebocoran memori; itu tidak merusak program, dan semua memori akan diambil secara otomatis ketika program berakhir.
Secara umum, Anda harus menghindari kebocoran memori. Pertama, karena seperti ketinggian di atas Anda dan bahan bakar kembali di hanggar, memori yang bocor dan tidak dapat dipulihkan tidak berguna; kedua, jauh lebih mudah untuk kode dengan benar, tidak bocor memori, pada awalnya daripada menemukan kebocoran memori nanti.
sumber
malloc
terlalu banyak memori itu adalah Hal Buruk. Itu masih bukan kebocoran . Ini bukan kebocoran sampai dan kecualimalloc
memori yang hilang referensi.Secara teori tidak, dalam praktiknya itu tergantung .
Itu benar-benar tergantung pada seberapa banyak data yang sedang dikerjakan program, seberapa sering program dijalankan dan apakah itu berjalan terus-menerus.
Jika saya memiliki program cepat yang membaca sejumlah kecil data membuat perhitungan dan keluar, kebocoran memori kecil tidak akan pernah diperhatikan. Karena program tidak berjalan terlalu lama dan hanya menggunakan sedikit memori, kebocorannya akan kecil dan dibebaskan ketika program ada.
Di sisi lain, jika saya memiliki program yang memproses jutaan catatan dan berjalan untuk waktu yang lama, kebocoran memori kecil mungkin akan menjatuhkan mesin dengan waktu yang cukup.
Adapun perpustakaan pihak ketiga yang memiliki kebocoran, jika mereka menyebabkan masalah baik memperbaiki perpustakaan atau menemukan alternatif yang lebih baik. Jika tidak menimbulkan masalah, apakah itu penting?
sumber
Banyak orang tampaknya berada di bawah kesan bahwa begitu Anda membebaskan memori, itu langsung dikembalikan ke sistem operasi dan dapat digunakan oleh program lain.
Ini tidak benar. Sistem operasi umumnya mengelola memori dalam halaman 4KiB.
malloc
dan jenis manajemen memori lainnya mendapatkan halaman dari OS dan mengaturnya sesuai keinginan mereka. Sangat mungkin itu tidakfree()
akan terjadi mengembalikan halaman ke sistem operasi, dengan asumsi bahwa program Anda akan malloc lebih banyak memori nanti.Saya tidak mengatakan itu
free()
tidak pernah mengembalikan memori ke sistem operasi. Itu bisa terjadi, terutama jika Anda membebaskan banyak memori. Tapi tidak ada jaminan.Fakta penting: Jika Anda tidak membebaskan memori yang tidak lagi Anda perlukan, mallocs lebih lanjut dijamin akan mengkonsumsi lebih banyak lagi memori. Tetapi jika Anda bebas dulu, malloc mungkin menggunakan kembali memori yang sudah dibebaskan.
Apa artinya ini dalam praktik? Ini berarti bahwa jika Anda tahu program Anda tidak akan membutuhkan lebih banyak memori mulai sekarang (misalnya sedang dalam tahap pembersihan), membebaskan memori tidak begitu penting. Namun jika program mungkin mengalokasikan lebih banyak memori nanti, Anda harus menghindari kebocoran memori - khususnya yang dapat terjadi berulang kali.
Lihat juga komentar ini untuk perincian lebih lanjut tentang mengapa membebaskan memori sebelum penghentian buruk.
Seorang komentator tampaknya tidak mengerti bahwa panggilan
free()
tidak secara otomatis memungkinkan program lain menggunakan memori yang dibebaskan. Tapi itulah inti dari jawaban ini!Jadi, untuk meyakinkan orang, saya akan menunjukkan contoh di mana gratis () tidak banyak berguna. Untuk membuat matematika mudah diikuti, saya akan berpura-pura bahwa OS mengelola memori dalam 4000 byte halaman.
Misalkan Anda mengalokasikan sepuluh ribu blok 100-byte (untuk kesederhanaan saya akan mengabaikan memori tambahan yang diperlukan untuk mengelola alokasi ini). Ini menghabiskan 1MB, atau 250 halaman. Jika Anda kemudian membebaskan 9000 blok ini secara acak, Anda hanya memiliki 1000 blok - tetapi semuanya tersebar di mana-mana. Secara statistik, sekitar 5 halaman akan kosong. 245 lainnya masing-masing akan memiliki setidaknya satu blok yang dialokasikan di dalamnya. Itu berjumlah 980KB memori, yang tidak mungkin dapat direklamasi oleh sistem operasi - meskipun Anda sekarang hanya memiliki 100KB yang dialokasikan!
Di sisi lain, Anda sekarang dapat malloc () 9000 blok lagi tanpa menambah jumlah memori yang sedang diikat oleh program Anda.
Bahkan ketika secara teknis
free()
dapat mengembalikan memori ke OS, itu mungkin tidak melakukannya. perlu mencapai keseimbangan antara beroperasi dengan cepat dan menghemat memori. Dan selain itu, sebuah program yang telah mengalokasikan banyak memori dan kemudian dibebaskan kemungkinan akan melakukannya lagi. Server web harus menangani permintaan demi permintaan demi permintaan - masuk akal untuk tetap menyediakan memori "kendur" agar Anda tidak perlu meminta memori OS setiap saat.free()
sumber
Secara konsep tidak ada yang salah dengan membersihkan os setelah aplikasi dijalankan.
Itu sangat tergantung pada aplikasi dan bagaimana itu akan dijalankan. Kebocoran yang terjadi terus-menerus dalam aplikasi yang perlu dijalankan selama berminggu-minggu harus dijaga, tetapi alat kecil yang menghitung hasil tanpa memori yang terlalu tinggi tidak perlu menjadi masalah.
Ada alasan mengapa banyak bahasa scripting tidak sampah mengumpulkan referensi siklus ... untuk pola penggunaannya, itu bukan masalah yang sebenarnya dan dengan demikian akan menjadi pemborosan sumber daya seperti memori yang terbuang.
sumber
Saya percaya jawabannya tidak, jangan pernah membiarkan memori bocor, dan saya punya beberapa alasan yang belum saya lihat secara eksplisit. Ada jawaban teknis yang bagus di sini, tetapi saya pikir jawaban yang sebenarnya bergantung pada alasan sosial / manusiawi.
(Pertama, perhatikan bahwa seperti yang disebutkan lainnya, kebocoran sebenarnya adalah ketika program Anda, pada titik mana saja, kehilangan jejak sumber daya memori yang telah dialokasikan. Di C, ini terjadi ketika Anda
malloc()
ke pointer dan membiarkan pointer meninggalkan ruang lingkup tanpa melakukanfree()
pertama.)Inti penting dari keputusan Anda di sini adalah kebiasaan. Ketika Anda kode dalam bahasa yang menggunakan pointer, Anda akan menggunakan pointer banyak . Dan pointer itu berbahaya; mereka adalah cara termudah untuk menambahkan segala macam masalah parah ke kode Anda.
Saat Anda menulis kode, terkadang Anda akan tertarik dan terkadang Anda lelah, marah, atau khawatir. Selama waktu yang agak terganggu, Anda mengkode lebih banyak pada autopilot. Efek autopilot tidak membedakan antara kode satu kali dan modul dalam proyek yang lebih besar. Selama masa itu, kebiasaan yang Anda bangun adalah apa yang akan berakhir dengan basis kode Anda.
Jadi tidak, jangan biarkan kebocoran memori untuk alasan yang sama bahwa Anda masih harus memeriksa titik-titik buta Anda ketika mengganti jalur bahkan jika Anda satu-satunya mobil di jalan saat ini. Selama masa ketika otak aktif Anda terganggu, kebiasaan baik adalah semua yang dapat menyelamatkan Anda dari salah langkah bencana.
Di luar masalah "kebiasaan", petunjuk itu rumit dan seringkali membutuhkan banyak kekuatan otak untuk melacak secara mental. Sebaiknya jangan "memperkeruh air" dalam hal penggunaan pointer Anda, terutama ketika Anda baru dalam pemrograman.
Ada aspek yang lebih sosial juga. Dengan penggunaan yang tepat dari
malloc()
danfree()
, siapa pun yang melihat kode Anda akan merasa nyaman; Anda mengelola sumber daya Anda. Namun, jika tidak, mereka akan segera mencurigai adanya masalah.Mungkin Anda telah mengetahui bahwa kebocoran memori tidak menyakiti apa pun dalam konteks ini, tetapi setiap pengelola kode Anda harus mengerjakannya juga di kepalanya ketika dia membaca sepotong kode itu. Dengan menggunakan
free()
Anda menghapus kebutuhan untuk mempertimbangkan masalah.Akhirnya, pemrograman adalah menulis model mental dari suatu proses ke bahasa yang tidak ambigu sehingga seseorang dan komputer dapat dengan sempurna memahami proses tersebut. Bagian penting dari praktik pemrograman yang baik tidak pernah memperkenalkan ambiguitas yang tidak perlu.
Pemrograman cerdas fleksibel dan generik. Pemrograman yang buruk bersifat mendua.
sumber
new
, sehingga menghilangkan sebagian besar kebocoran memori segera. Hanya jika Anda benar-benar harus Anda gunakannew
. Hasil itunew
harus segera dimasukkan ke dalam smart pointer. Jika Anda mengikuti kedua aturan itu, Anda tidak akan pernah membocorkan memori (kecuali bug di perpustakaan). Satu-satunya kasing yang tersisa adalahshared_ptr
siklus, yang dalam hal ini Anda harus tahu untuk menggunakannyaweak_ptr
.Saya pikir dalam situasi Anda jawabannya mungkin tidak apa-apa. Tetapi Anda pasti perlu mendokumentasikan bahwa kebocoran memori adalah keputusan sadar. Anda tidak ingin pemrogram pemeliharaan datang, menampar kode Anda di dalam suatu fungsi, dan menyebutnya jutaan kali. Jadi, jika Anda membuat keputusan bahwa kebocoran tidak masalah, Anda perlu mendokumentasikannya (DALAM SURAT BESAR) bagi siapa pun yang mungkin harus mengerjakan program di masa mendatang.
Jika ini adalah perpustakaan pihak ketiga Anda mungkin terjebak. Namun yang pasti mendokumentasikan bahwa kebocoran ini terjadi.
Tetapi pada dasarnya jika kebocoran memori adalah kuantitas yang dikenal seperti buffer 512 KB atau sesuatu, maka itu bukan masalah. Jika kebocoran memori terus bertambah seperti setiap kali Anda memanggil perpustakaan, panggilan memori Anda meningkat sebesar 512KB dan tidak dibebaskan, maka Anda mungkin memiliki masalah. Jika Anda mendokumentasikannya dan mengontrol berapa kali panggilan dieksekusi, itu mungkin dapat dikelola. Tapi kemudian Anda benar-benar membutuhkan dokumentasi karena 512 tidak banyak, 512 lebih dari satu juta panggilan banyak.
Anda juga perlu memeriksa dokumentasi sistem operasi Anda. Jika ini adalah perangkat tertanam mungkin ada sistem operasi yang tidak membebaskan semua memori dari program yang keluar. Saya tidak yakin, mungkin ini tidak benar. Tapi itu layak untuk dilihat.
sumber
Saya akan memberikan jawaban yang tidak populer tetapi praktis bahwa selalu salah untuk membebaskan memori kecuali jika hal itu akan mengurangi penggunaan memori program Anda . Misalnya program yang membuat satu alokasi atau serangkaian alokasi untuk memuat dataset yang akan digunakan sepanjang hayatnya tidak perlu membebaskan apa pun. Dalam kasus yang lebih umum dari sebuah program besar dengan kebutuhan memori yang sangat dinamis (bayangkan browser web), Anda harus jelas membebaskan memori yang tidak lagi Anda gunakan sesegera mungkin (misalnya menutup tab / dokumen / dll.) , tetapi tidak ada alasan untuk membebaskan apa pun ketika pengguna memilih klik "keluar", dan melakukannya sebenarnya berbahaya bagi pengalaman pengguna.
Mengapa? Membebaskan memori membutuhkan memori sentuh. Bahkan jika implementasi malloc sistem Anda tidak menyimpan metadata yang berdekatan dengan blok memori yang dialokasikan, Anda kemungkinan akan berjalan dengan struktur rekursif hanya untuk menemukan semua pointer yang Anda butuhkan untuk membebaskan.
Sekarang, misalkan program Anda telah bekerja dengan volume data yang besar, tetapi belum menyentuh sebagian besar untuk sementara waktu (sekali lagi, browser web adalah contoh yang bagus). Jika pengguna menjalankan banyak aplikasi, sebagian besar data itu kemungkinan telah ditukar ke disk. Jika Anda baru saja keluar (0) atau kembali dari utama, ia keluar secara instan. Pengalaman pengguna yang luar biasa. Jika Anda kesulitan mencoba untuk membebaskan semuanya, Anda dapat menghabiskan 5 detik atau lebih untuk menukar semua data kembali, hanya untuk membuangnya segera setelah itu. Buang-buang waktu pengguna. Buang-buang baterai laptop. Buang aus pada hard disk.
Ini bukan hanya teoretis. Setiap kali saya menemukan diri saya dengan terlalu banyak aplikasi dimuat dan disk mulai meronta-ronta, saya bahkan tidak mempertimbangkan mengklik "keluar". Saya sampai di terminal secepat mungkin dan ketik killall -9 ... karena saya tahu "keluar" hanya akan memperburuknya.
sumber
Saya yakin bahwa seseorang dapat datang dengan alasan untuk mengatakan Ya, tetapi itu bukan saya. Alih-alih mengatakan tidak, saya akan mengatakan bahwa ini seharusnya tidak menjadi pertanyaan ya / tidak. Ada beberapa cara untuk mengelola atau mengatasi kebocoran memori, dan banyak sistem memilikinya.
Ada sistem NASA pada perangkat yang meninggalkan bumi yang merencanakan ini. Sistem akan secara otomatis reboot setiap kali sehingga kebocoran memori tidak menjadi fatal bagi keseluruhan operasi. Hanya sebuah contoh penahanan.
sumber
Jika Anda mengalokasikan memori dan menggunakannya hingga baris terakhir dari program Anda, itu bukan kebocoran. Jika Anda mengalokasikan memori dan melupakannya, bahkan jika jumlah memori tidak bertambah, itu masalah. Memori yang dialokasikan tetapi tidak digunakan itu dapat menyebabkan program lain berjalan lebih lambat atau tidak sama sekali.
sumber
Saya dapat mengandalkan di satu sisi jumlah kebocoran "jinak" yang telah saya lihat seiring waktu.
Jadi jawabannya ya sangat berkualitas.
Sebuah contoh. Jika Anda memiliki sumber tunggal yang memerlukan penyangga untuk menyimpan antrian atau deik melingkar tetapi tidak tahu seberapa besar penyangga akan perlu dan tidak mampu membayar overhead penguncian atau setiap pembaca, maka alokasikan penyangga berlipat ganda secara eksponensial tetapi tidak membebaskan yang lama akan membocorkan jumlah memori yang dibatasi per antrian / deque. Manfaat untuk ini adalah mereka mempercepat setiap akses secara dramatis dan dapat mengubah asimtotik dari solusi multiprosesor dengan tidak pernah mempertaruhkan pertengkaran untuk kunci.
Saya telah melihat pendekatan ini digunakan untuk keuntungan besar untuk hal-hal dengan jumlah yang sangat jelas tetap seperti per-CPU mencuri pekerjaan, dan ke tingkat yang jauh lebih rendah dalam buffer yang digunakan untuk memegang
/proc/self/maps
negara tunggal di pengumpul sampah Hans Boehm yang konservatif untuk C / C ++, yang digunakan untuk mendeteksi set root, dll.Meskipun secara teknis bocor, kedua kasing ini dibatasi ukurannya dan dalam kasing bundar yang tumbuh, ada kemenangan kinerja yang sangat besar dengan imbalan faktor peningkatan 2 peningkatan dalam penggunaan memori untuk antrian.
sumber
Jika Anda mengalokasikan banyak tumpukan di awal program Anda, dan Anda tidak membebaskannya saat Anda keluar, itu bukan kebocoran memori per se. Kebocoran kehabisan memori adalah ketika program Anda memutar lebih dari satu bagian kode, dan kode itu mengalokasikan tumpukan dan kemudian "kehilangan jejak" dari itu tanpa membebaskannya.
Bahkan, tidak perlu membuat panggilan untuk membebaskan () atau menghapus tepat sebelum Anda keluar. Ketika proses keluar, semua memorinya diambil kembali oleh OS (ini tentu saja dengan POSIX. Pada OS lain - terutama yang tertanam - YMMV).
Satu-satunya peringatan yang saya miliki dengan tidak membebaskan memori pada waktu keluar adalah bahwa jika Anda pernah refactor program Anda sehingga, misalnya, menjadi layanan yang menunggu input, melakukan apa pun yang program Anda lakukan, kemudian berputar-putar untuk menunggu panggilan layanan lain, lalu apa yang sudah Anda kodekan dapat berubah menjadi kebocoran memori.
sumber
ini sangat spesifik domain sehingga hampir tidak layak dijawab. gunakan kepalamu yang menakutkan.
dan ada spektrum situasi menengah.
biaya peluang ($$$) untuk menunda rilis produk untuk memperbaiki semua tetapi kebocoran memori terburuk biasanya mengerdilkan perasaan "ceroboh atau tidak profesional". Bos Anda membayar Anda untuk menghasilkan uang, bukan untuk mendapatkan perasaan hangat dan tidak jelas.
sumber
Pertama-tama Anda harus menyadari bahwa ada perbedaan besar antara kebocoran memori yang dirasakan dan kebocoran memori yang sebenarnya. Sangat sering alat analisis akan melaporkan banyak ikan haring merah, dan memberi label sesuatu telah bocor (memori atau sumber daya seperti gagang dll) di tempat yang sebenarnya tidak. Seringkali ini disebabkan oleh arsitektur alat analisis. Misalnya, alat analisis tertentu akan melaporkan objek waktu berjalan sebagai kebocoran memori karena tidak pernah melihat objek tersebut dibebaskan. Tapi deallokasi terjadi dalam kode shutdown runtime, yang mungkin tidak bisa dilihat oleh alat analisis.
Dengan itu, masih ada saat-saat ketika Anda akan memiliki kebocoran memori aktual yang sangat sulit ditemukan atau sangat sulit untuk diperbaiki. Jadi sekarang pertanyaannya adalah apakah pernah meninggalkan mereka dalam kode?
Jawaban yang ideal adalah, "tidak, tidak pernah." Jawaban yang lebih pragmatis mungkin "tidak, hampir tidak pernah." Sangat sering dalam kehidupan nyata Anda memiliki jumlah sumber daya dan waktu terbatas untuk menyelesaikan dan daftar tugas yang tak ada habisnya. Ketika salah satu tugasnya adalah menghilangkan kebocoran memori, hukum pengembalian yang semakin berkurang sering kali muncul. Anda bisa menghilangkan 98% dari semua kebocoran memori dalam suatu aplikasi dalam seminggu, tetapi 2% sisanya mungkin membutuhkan waktu berbulan-bulan. Dalam beberapa kasus bahkan mungkin tidak mungkin untuk menghilangkan kebocoran tertentu karena arsitektur aplikasi tanpa refactoring kode yang utama. Anda harus mempertimbangkan biaya dan manfaat menghilangkan sisa 2%.
sumber
Dalam konteks pertanyaan semacam ini adalah segalanya. Secara pribadi saya tidak tahan kebocoran, dan dalam kode saya saya berusaha keras untuk memperbaikinya jika mereka muncul, tetapi tidak selalu layak untuk memperbaiki kebocoran, dan ketika orang membayar saya pada jam yang saya miliki pada kesempatan mengatakan kepada mereka itu tidak layak biaya saya bagi saya untuk memperbaiki kebocoran dalam kode mereka. Biarkan saya memberi Anda sebuah contoh:
Saya sedang merencanakan proyek, melakukan beberapa pekerjaan perf dan memperbaiki banyak bug. Ada kebocoran selama inisialisasi aplikasi yang saya lacak, dan sepenuhnya dipahami. Untuk memperbaikinya dengan benar, diperlukan sekitar satu hari atau lebih untuk mengembalikan kode yang berfungsi. Saya bisa melakukan sesuatu yang gila (seperti memasukkan nilai ke dalam global dan meraihnya pada titik tertentu, saya tahu itu tidak lagi digunakan untuk membebaskan), tetapi itu hanya akan menyebabkan lebih banyak kebingungan bagi orang berikutnya yang harus menyentuh kode.
Secara pribadi saya tidak akan menulis kode seperti itu di tempat pertama, tetapi kebanyakan dari kita tidak bisa selalu bekerja pada basis kode yang dirancang dengan baik, dan kadang-kadang Anda harus melihat hal-hal ini secara pragmatis. Jumlah waktu yang diperlukan untuk memperbaiki bahwa kebocoran 150 byte malah bisa dihabiskan untuk membuat perbaikan algoritmik yang mengurangi megabita ram.
Pada akhirnya, saya memutuskan bahwa membocorkan 150 byte untuk aplikasi yang digunakan di sekitar pertunjukan ram dan berlari pada mesin khusus tidak layak untuk memperbaikinya, jadi saya menulis komentar yang mengatakan bahwa itu bocor, apa yang perlu diubah untuk memperbaiki itu, dan mengapa itu tidak layak saat itu.
sumber
Sementara sebagian besar jawaban berkonsentrasi pada kebocoran memori nyata (yang tidak pernah OK, karena mereka adalah tanda pengkodean yang ceroboh), bagian dari pertanyaan ini tampak lebih menarik bagi saya:
Jika memori terkait digunakan, Anda tidak dapat membebaskannya sebelum program berakhir. Apakah gratis dilakukan oleh program keluar atau oleh OS tidak masalah. Selama ini didokumentasikan, sehingga perubahan tidak menyebabkan kebocoran memori nyata, dan selama tidak ada C ++ destructor atau fungsi pembersihan C yang terlibat dalam gambar. File yang tidak ditutup mungkin terungkap melalui kebocoran
FILE
objek yang , tetapi fclose () yang hilang juga dapat menyebabkan buffer tidak memerah.Jadi, kembali ke kasus aslinya, IMHO benar-benar baik-baik saja, sehingga Valgrind, salah satu pendeteksi kebocoran paling kuat, akan menangani kebocoran seperti itu hanya jika diminta. Pada Valgrind, ketika Anda menimpa pointer tanpa membebaskannya sebelumnya, itu dianggap sebagai kebocoran memori, karena itu lebih mungkin terjadi lagi dan menyebabkan tumpukan tumbuh tanpa henti.
Kemudian, tidak ada blok memori nfreed yang masih dapat dijangkau. Orang bisa memastikan untuk membebaskan mereka semua di pintu keluar, tapi itu hanya buang-buang waktu saja. Intinya adalah apakah mereka bisa dibebaskan sebelumnya . Menurunkan konsumsi memori berguna dalam hal apa pun.
sumber
Saya setuju dengan vfilby - itu tergantung. Di Windows, kami memperlakukan kebocoran memori sebagai bug yang relatif serius. Tapi, itu sangat tergantung pada komponennya.
Misalnya, kebocoran memori tidak terlalu serius untuk komponen yang jarang berjalan, dan untuk jangka waktu terbatas. Komponen-komponen ini berjalan, bekerja, kemudian keluar. Ketika mereka keluar semua ingatan mereka dibebaskan secara implisit.
Namun, kebocoran memori dalam layanan atau komponen jangka panjang lainnya (seperti shell) sangat serius. Alasannya adalah bahwa bug ini 'mencuri' memori dari waktu ke waktu. Satu-satunya cara untuk memulihkan ini adalah me-restart komponen. Kebanyakan orang tidak tahu cara me-restart layanan atau shell - jadi jika kinerja sistem mereka menderita, mereka hanya reboot.
Jadi, jika Anda memiliki kebocoran - evaluasi dampaknya dengan dua cara
Foredecker
sumber
Bahkan jika Anda yakin bahwa kebocoran memori 'dikenal' Anda tidak akan menyebabkan kekacauan, jangan lakukan itu. Paling-paling, itu akan membuka jalan bagi Anda untuk membuat kesalahan yang serupa dan mungkin lebih kritis pada waktu dan tempat yang berbeda.
Bagi saya, bertanya seperti bertanya, "Bisakah saya memecah lampu merah pada jam 3 pagi ketika tidak ada orang di sekitar?". Baiklah, itu mungkin tidak menyebabkan masalah pada waktu itu tetapi itu akan memberikan tuas bagi Anda untuk melakukan hal yang sama di jam sibuk!
sumber
Tidak, Anda seharusnya tidak memiliki kebocoran bahwa OS akan membersihkan untuk Anda. Alasannya (tidak disebutkan dalam jawaban di atas sejauh yang saya bisa periksa) adalah bahwa Anda tidak pernah tahu kapan main Anda () akan digunakan kembali sebagai fungsi / modul di program lain . Jika main () Anda menjadi fungsi yang sering disebut dalam perangkat lunak orang lain - perangkat lunak ini akan mengalami kebocoran memori yang memakan memori seiring waktu.
KIV
sumber
Saya kira tidak apa-apa jika Anda menulis sebuah program yang dimaksudkan untuk membocorkan memori (yaitu untuk menguji dampak kebocoran memori pada kinerja sistem).
sumber
Saya terkejut melihat begitu banyak definisi yang salah tentang apa sebenarnya kebocoran memori itu. Tanpa definisi yang konkret, diskusi tentang apakah itu hal yang buruk atau tidak akan sia-sia.
Seperti yang ditunjukkan oleh beberapa komentator dengan tepat, kebocoran memori hanya terjadi ketika memori yang dialokasikan oleh suatu proses keluar dari ruang lingkup sejauh proses tidak lagi dapat merujuk atau menghapusnya.
Suatu proses yang mengambil semakin banyak memori tidak selalu bocor. Selama ia dapat merujuk dan membatalkan alokasi memori itu, maka ia tetap berada di bawah kendali proses yang eksplisit dan belum bocor. Prosesnya mungkin dirancang dengan buruk, terutama dalam konteks sistem di mana memori terbatas, tetapi ini tidak sama dengan kebocoran. Sebaliknya, kehilangan ruang lingkup, katakanlah, buffer 32 byte masih bocor, meskipun jumlah memori yang bocor kecil. Jika Anda merasa ini tidak penting, tunggu sampai seseorang membungkus algoritma di sekitar panggilan perpustakaan Anda dan menyebutnya 10.000 kali.
Saya tidak melihat alasan apa pun untuk mengizinkan kebocoran pada kode Anda sendiri, betapapun kecilnya. Bahasa pemrograman modern seperti C dan C ++ berusaha keras untuk membantu programmer mencegah kebocoran seperti itu dan jarang ada argumen yang baik untuk tidak mengadopsi teknik pemrograman yang baik - terutama ketika digabungkan dengan fasilitas bahasa tertentu - untuk mencegah kebocoran.
Mengenai kode yang ada atau pihak ketiga, di mana kendali Anda atas kualitas atau kemampuan untuk melakukan perubahan mungkin sangat terbatas, tergantung pada tingkat keparahan kebocoran, Anda mungkin dipaksa untuk menerima atau mengambil tindakan mitigasi seperti memulai kembali proses Anda secara teratur untuk mengurangi efek kebocoran.
Mungkin tidak mungkin untuk mengubah atau mengganti kode yang ada (bocor), dan karenanya Anda mungkin akan menerimanya. Namun, ini tidak sama dengan menyatakan bahwa itu OK.
sumber
Ini benar-benar bukan kebocoran jika disengaja dan tidak menjadi masalah kecuali jumlah memori yang signifikan, atau dapat tumbuh menjadi jumlah memori yang signifikan. Cukup umum untuk tidak membersihkan alokasi global selama masa program. Jika kebocoran ada di server atau aplikasi yang berjalan lama, tumbuh seiring waktu, maka itu masalah.
sumber
Saya pikir Anda telah menjawab pertanyaan Anda sendiri. Kelemahan terbesar adalah bagaimana mereka mengganggu alat deteksi kebocoran memori, tapi saya pikir kelemahan itu adalah kelemahan BESAR untuk jenis aplikasi tertentu.
Saya bekerja dengan aplikasi server lama yang seharusnya solid tetapi mereka memiliki kebocoran dan para global tidak menghalangi alat pendeteksi memori. Ini masalah besar.
Dalam buku "Ciutkan" oleh Jared Diamond, penulis bertanya-tanya tentang apa yang dipikirkan lelaki itu yang menebang pohon terakhir di Pulau Paskah, pohon yang ia perlukan untuk membangun sampan untuk turun dari pulau. Saya bertanya-tanya tentang hari bertahun-tahun yang lalu ketika global pertama itu ditambahkan ke basis kode kami. ITULAH hari itu seharusnya ditangkap.
sumber
Saya melihat masalah yang sama dengan semua pertanyaan skenario seperti ini: Apa yang terjadi ketika program berubah, dan tiba-tiba sedikit kebocoran memori dipanggil sepuluh juta kali dan akhir program Anda berada di tempat yang berbeda sehingga itu penting? Jika ada di perpustakaan lalu catat bug dengan pengelola perpustakaan, jangan bocor ke kode Anda sendiri.
sumber
Saya akan menjawab tidak.
Secara teori, sistem operasi akan membersihkan setelah Anda jika Anda meninggalkan kekacauan (sekarang itu hanya kasar, tetapi karena komputer tidak memiliki perasaan itu mungkin dapat diterima). Tetapi Anda tidak dapat mengantisipasi setiap situasi yang mungkin terjadi ketika program Anda dijalankan. Oleh karena itu (kecuali jika Anda dapat melakukan bukti formal dari beberapa perilaku), membuat kebocoran memori tidak bertanggung jawab dan ceroboh dari sudut pandang profesional.
Jika komponen pihak ketiga bocor memori, ini adalah argumen yang sangat kuat untuk tidak menggunakannya, tidak hanya karena efek yang akan terjadi tetapi juga karena itu menunjukkan bahwa programer bekerja dengan sembrono dan bahwa ini juga dapat mempengaruhi metrik lainnya. Sekarang, ketika mempertimbangkan sistem lawas ini sulit (pertimbangkan komponen penelusuran web: sepengetahuan saya, semuanya bocor memori) tetapi itu harus menjadi norma.
sumber
Secara historis, itu penting pada beberapa sistem operasi dalam beberapa kasus tepi. Kasus tepi ini bisa ada di masa depan.
Berikut ini sebuah contoh, pada SunOS di era Sun 3, ada masalah jika suatu proses menggunakan exec (atau lebih tradisional menggunakan fork dan kemudian exec), proses baru berikutnya akan mewarisi jejak memori yang sama dengan induknya dan tidak dapat menyusut. . Jika suatu proses induk mengalokasikan ½ gig memori dan tidak membebaskannya sebelum memanggil exec, proses anak akan mulai menggunakan ½ manggung yang sama (meskipun itu tidak dialokasikan). Perilaku ini paling baik ditunjukkan oleh SunTools (sistem windowing default mereka), yang merupakan memory hog. Setiap aplikasi yang dihasilkan dibuat melalui fork / exec dan mewarisi jejak SunTools, dengan cepat mengisi ruang swap.
sumber
Ini sudah dibahas ad mual . Intinya adalah bahwa kebocoran memori adalah bug dan harus diperbaiki. Jika perpustakaan pihak ketiga bocor memori, itu membuat orang bertanya-tanya apa lagi yang salah dengan itu, bukan? Jika Anda sedang membangun mobil, apakah Anda akan menggunakan mesin yang terkadang bocor oli? Lagi pula, orang lain yang membuat mesinnya, jadi itu bukan kesalahan Anda dan Anda tidak dapat memperbaikinya, bukan?
sumber
Umumnya kebocoran memori dalam aplikasi yang berdiri sendiri tidak berakibat fatal, karena akan dibersihkan ketika program keluar.
Apa yang Anda lakukan untuk program Server yang dirancang agar tidak keluar?
Jika Anda adalah jenis programmer yang tidak merancang dan mengimplementasikan kode di mana sumber daya dialokasikan dan dirilis dengan benar, maka saya tidak ingin ada hubungannya dengan Anda atau kode Anda. Jika Anda tidak ingin membersihkan memori yang bocor, bagaimana dengan kunci Anda? Apakah Anda membiarkan mereka nongkrong di sana juga? Apakah Anda meninggalkan sedikit file sementara yang bertebaran di berbagai direktori?
Bocoran memori itu dan biarkan program membersihkannya? Sama sekali tidak. Ini kebiasaan buruk, yang mengarah ke bug, bug, dan lebih banyak bug.
Bersihkan dirimu. Yo momma tidak bekerja lagi di sini.
sumber
Sebagai aturan umum, jika Anda memiliki kebocoran memori yang Anda rasa tidak bisa Anda hindari, maka Anda perlu berpikir lebih keras tentang kepemilikan objek.
Tetapi untuk pertanyaan Anda, jawaban saya singkatnya adalah Dalam kode produksi, ya. Selama pengembangan, tidak . Ini mungkin tampak mundur, tapi inilah alasan saya:
Dalam situasi yang Anda jelaskan, di mana memori disimpan hingga akhir program, tidak apa-apa untuk tidak melepaskannya. Setelah proses Anda keluar, OS akan tetap bersih. Bahkan, itu mungkin membuat pengalaman pengguna lebih baik: Dalam permainan yang telah saya kerjakan, para programmer berpikir akan lebih bersih untuk membebaskan semua memori sebelum keluar, yang menyebabkan penutupan program membutuhkan waktu hingga setengah menit! Perubahan cepat yang baru saja disebut keluar () bukannya membuat proses menghilang dengan segera, dan menempatkan pengguna kembali ke desktop di tempat yang diinginkannya.
Namun, Anda benar tentang alat debugging: Mereka akan cocok, dan semua positif palsu mungkin membuat memori nyata Anda bocor. Dan karena itu, selalu tulis kode debug yang membebaskan memori, dan nonaktifkan saat Anda mengirim.
sumber