Apakah kebocoran memori pernah baik-baik saja? [Tutup]

231

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.

Imbue
sumber
50
Jika konsumsi memori tidak bertambah seiring waktu, itu bukan kebocoran.
mpez0
4
Sebagian besar aplikasi (termasuk semua program .NET) memiliki setidaknya beberapa buffer yang dialokasikan satu kali dan tidak pernah dibebaskan secara eksplisit., Sehingga definisi mpez0 lebih berguna.
Ben Voigt
2
Ya, jika Anda memiliki memori tak terbatas.
pengguna
Kebocoran "jinak" (jika ada hal seperti itu) bukan positif palsu - ini adalah kebocoran yang terdeteksi dengan sangat benar. Deteksi kebocoran, bahkan untuk kebocoran yang secara pribadi Anda rasa tidak ingin diperbaiki, adalah alasan utama detektor kebocoran ada.
cHao
1
@ mpez0 "Jika konsumsi memori tidak bertambah seiring waktu, itu bukan kebocoran"? Itu bukan definisi kebocoran memori. Kebocoran adalah memori yang telah bocor, yang berarti itu tidak dibebaskan dan Anda tidak memiliki referensi untuk itu lagi, maka tidak mungkin bagi Anda untuk pernah membebaskannya lagi. Apakah tumbuh atau tidak tidak relevan.
Mecki

Jawaban:

329

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.

JohnMcG
sumber
57
Benar dan tidak benar pada saat bersamaan. Ultimate kebanyakan dari kita adalah budak berupah dan keinginan untuk pengerjaan harus mengambil kursi belakang dengan persyaratan bisnis. Jika perpustakaan pihak ke-3 itu mengalami kebocoran dan menghemat 2 minggu kerja, mungkin ada kasus bisnis untuk menggunakannya, dll ...
Cervo
3
Saya tetap akan menggunakan perpustakaan, jika itu adalah sesuatu yang saya butuhkan dan tidak ada alternatif yang layak, tetapi saya akan mencatat bug pada pengelola.
menyapa
7
Walaupun saya pribadi akan menjawab dengan jawaban yang persis sama, ada beberapa program yang hampir tidak membebaskan memori sama sekali. Alasannya adalah mereka a) dimaksudkan untuk berjalan pada OS yang membebaskan memori, dan b) dirancang untuk tidak berjalan terlalu lama. Kendala langka untuk suatu program memang, tetapi saya menerima ini sebagai valid sempurna.
2
Untuk menambahkan beberapa alasan untuk pemeriksaan awal: ketika alat debug Anda dibanjiri dengan kebocoran "jinak", bagaimana Anda akan menemukan yang "asli"? Jika Anda menambahkan fitur batch, dan tiba-tiba kebocoran 1K / jam Anda menjadi 1K / detik?
peterchen
5
Hmm "tidak bocor memori" "sempurna"?
JohnMcG
80

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.

Jim C
sumber
12
Secara teknis, kebocoran adalah memori yang dialokasikan dan semua referensi untuk itu hilang. Tidak membatalkan memori pada akhirnya hanya malas.
Martin York
17
Jika Anda memiliki kebocoran memori 1 kali sebesar 4 GB, itu masalah.
John Dibling
21
Tidak masalah apakah itu tumbuh atau tidak. Program lain tidak dapat menggunakan memori jika Anda mengalokasikannya.
Bill the Lizard
8
> Program lain tidak dapat menggunakan memori jika Anda mengalokasikannya. Ya, OS selalu dapat menukar memori Anda ke disk, dan memungkinkan aplikasi lain menggunakan RAM yang tidak Anda manfaatkan.
Max Lybbert
4
Jika program ini berumur pendek, maka kebocoran mungkin tidak terlalu buruk. Juga, walaupun BUKAN ideal, paging tidak semahal beberapa di sini membuatnya, karena program tidak tertarik pada memori itu (Dan dengan demikian tidak akan bertukar sepanjang waktu) - kecuali, tentu saja, Anda memiliki GC ...
Arafangion
79

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:

#define BLK ((size_t)1024)
while(1){
    void * vp = malloc(BLK);
}

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

int main(){
    void * vp = malloc(LOTS);
    // Go do something useful
    return 0;
}

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.

Charlie Martin
sumber
Sekarang pertimbangkan beberapa lusin alokasi ini. Sekarang pertimbangkan untuk memindahkan tubuh "utama" ke rutin yang dipanggil beberapa kali. Nikmati. - Saya setuju dengan sentimen bahwa ini bukan masalah besar dalam skenario ini, tetapi skenario berubah. Seperti yang mereka katakan, selalu menulis kode seolah-olah pria yang merawatnya tahu di mana Anda tinggal.
peterchen
2
Yah, intinya adalah bahwa memori yang malloc'ed dan ditahan sampai program memanggil _exit () tidak "bocor".
Charlie Martin
1
Ini adalah kebocoran memori dan dapat merusak program Anda. Alokasi di masa mendatang dapat gagal dari proses ini karena saya yakin Anda sedang memeriksa malloc yang dikembalikan ke mana-mana. dengan lebih menggunakan memori, seperti dalam situasi tertanam di mana memor langka ini bisa menjadi perbedaan antara hidup dan mati.
MikeJ
10
Mike, itu tidak benar. Dalam lingkungan C yang sesuai, mengakhiri main membebaskan semua sumber daya proses. Di lingkungan tertanam seperti yang Anda gambarkan, Anda mungkin melihat situasi itu, tetapi Anda tidak akan memiliki utama. Sekarang, saya akui bahwa mungkin ada lingkungan tertanam cacat yang ini tidak benar, tapi kemudian saya telah melihat lingkungan cacat yang tidak dapat mengatasi + = dengan benar juga.
Charlie Martin
3
Ya, Anda sekarang telah menemukan bahwa jika Anda mallocterlalu banyak memori itu adalah Hal Buruk. Itu masih bukan kebocoran . Ini bukan kebocoran sampai dan kecuali mallocmemori yang hilang referensi.
Charlie Martin
39

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?

ayolah
sumber
Saya tidak tahu apakah Anda membaca seluruh pertanyaan saya atau tidak. Saya mengatakan bahwa memori digunakan sampai akhir aplikasi. Itu tidak tumbuh seiring waktu. Satu-satunya tidak, tidak, tidak ada panggilan untuk membebaskan / menghapus.
Imbue
2
Maka itu bukan kebocoran memori. Kebocoran memori adalah sejumlah kecil memori yang tidak terpakai tetapi tidak terpakai, jumlah ini semakin besar dari waktu ke waktu. Yang Anda bicarakan adalah tetesan memori. Jangan khawatirkan diri Anda dengan ini kecuali tetesan Anda sangat besar.
vfilby
"Jika tidak menimbulkan masalah, apakah itu penting?" Tidak, tidak masalah sama sekali. Saya berharap lebih banyak orang mendapatkannya daripada menjadi religius.
Imbue
2
@ John: Biasanya itu bukan masalah pengembang malas dan lebih banyak pertanyaan tentang pengembangan perangkat lunak. Kita semua membuat kesalahan, bug adalah perdagangan kita; kita membuat mereka memperbaikinya, itulah yang kita lakukan. Itu selalu merupakan keseimbangan antara biaya dimuka dan pemeliharaan jangka panjang, keseimbangan itu tidak pernah mudah.
vfilby
1
John, saya 100% setuju dengan Anda .. Imbum Pertanyaannya hampir, "berapa banyak yang Anda terima". Ceroboh ceroboh .. Bagaimana kalau saya meninggalkan udang di belakang monitor Anda. bau itu bau. Setiap kali kita menyerah, industri kita sedikit runtuh. Jika Anda tahu ada kebocoran dan Anda tahu Anda penyebabnya, maka Anda harus memperbaikinya.
baash05
37

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. mallocdan 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 teknisfree() 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()

Artelius
sumber
1
Bagaimana jika, program lain membutuhkan memori yang tidak perlu ditahan oleh program Anda, maka meskipun Anda mungkin tidak memerlukan mallocs lagi, kosongkan () ruang memori yang tidak digunakan :)
MN
2
Anda benar-benar kehilangan maksud saya. Saat Anda mengosongkan () memori, program lain tidak dapat menggunakannya !! (Kadang-kadang mereka bisa, terutama jika Anda membebaskan banyak memori. Tapi seringkali, mereka tidak bisa!) Saya akan mengedit posting saya untuk membuat ini lebih jelas.
Artelius
27

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.

kasperjj
sumber
Tentang bahasa scripting: Python menggunakan penghitungan ulang tetapi memiliki GC hanya untuk membebaskan referensi siklus. Dalam bahasa lain, pemrogram sering kali menghindari referensi siklis secara eksplisit, yang menciptakan masalah lain.
Blaisorblade
Versi PHP yang lebih lama tidak melepaskan memori, mereka hanya berlari dari awal hingga akhir yang tumbuh dalam memori - setelah waktu eksekusi yang biasanya 0,1 detik, skrip akan keluar, dan semua memori akan direklamasi.
Arafangion
19

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 melakukan free()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()dan free(), 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.

Jason L.
sumber
Saya suka ide kebiasaan. Saya juga setuju. Jika saya melihat kebocoran memori, saya selalu bertanya-tanya sudut lain apa yang dipotong oleh coder. Terutama jika itu sudah jelas
baash05
Ini adalah jawaban terbaik sejauh ini. Saya telah memprogram dalam C ++ selama 5 tahun sekarang dan saya tidak pernah menulis kebocoran memori tunggal. Alasannya adalah saya tidak menulis kode yang cenderung bocor memori. Desain C ++ yang baik jarang Anda gunakan new, sehingga menghilangkan sebagian besar kebocoran memori segera. Hanya jika Anda benar-benar harus Anda gunakan new. Hasil itu newharus 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 adalah shared_ptrsiklus, yang dalam hal ini Anda harus tahu untuk menggunakannya weak_ptr.
David Stone
15

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.

Cervo
sumber
3
"Tapi Anda pasti perlu mendokumentasikan bahwa kebocoran memori adalah keputusan sadar." Terima kasih Tuhan. Poin terbaik sejauh ini.
pestophagous
15

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.

R .. GitHub BERHENTI MEMBANTU ES
sumber
5
Cintai kutipan ini dari Raymond Chen: "Bangunan itu sedang dihancurkan. Jangan repot-repot menyapu lantai dan mengosongkan tempat sampah dan menghapus papan tulis. Dan jangan berbaris di pintu keluar gedung sehingga semua orang bisa memindahkan barang mereka di / magnet ke luar. Yang Anda lakukan hanyalah membuat tim pembongkaran menunggu Anda untuk menyelesaikan tugas-tugas pembersihan rumah yang tidak berguna ini. " ( blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683 )
Andreas Magnusson
11

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.

pearcewg
sumber
Itu sebenarnya contoh penuaan perangkat lunak. Subjek studi yang menarik.
Konrad Rudolph
Reboot otomatis sering sekali, ya? NASA, ya? (* lihat CD instalasi Microsoft Windows lama *) Ini menjelaskan banyak hal ...
Christian Severin
8

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.

Bill the Lizard
sumber
Tidak juga, karena jika tidak digunakan, itu hanya akan keluar. Saat aplikasi keluar, semua memori dilepaskan.
Eclipse
Selama itu dialokasikan program lain tidak akan dapat menggunakannya. Itu tidak akan keluar jika Anda tidak mengalokasikannya.
Bill the Lizard
Tentu saja - itulah yang dimaksud dengan memori virtual. Anda dapat memiliki 1 GB RAM aktual, namun memiliki 4 proses yang masing-masing mengalokasikan sepenuhnya 2 GB memori virtual (selama file halaman Anda cukup besar).
Eclipse
Tentu saja, Anda akan mendapatkan masalah paging yang buruk jika masing-masing proses tersebut secara aktif menggunakan semua memori itu.
Eclipse
Oke, saya mengerti apa yang Anda bicarakan sekarang. Jika Anda membatalkan alokasi memori yang tidak Anda gunakan, Anda akan mengurangi kebutuhan paging. Jika Anda tetap mengalokasikannya, aplikasi Anda akan tetap menyimpannya ketika halaman itu dikembalikan.
Bill the Lizard
8

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/mapsnegara 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.

Edward KMETT
sumber
1
Anda dapat menggunakan penunjuk bahaya untuk mencegah kebocoran.
Demi
8

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.

nsayer
sumber
Saya mohon untuk berbeda. Itu adalah "kebocoran memori per se".
Konrad Rudolph
Ini bukan kebocoran sampai Anda "kehilangan" referensi ke objek. Agaknya, jika memori digunakan untuk seumur hidup program, maka itu tidak bocor. Jika referensi tidak hilang sampai keluar () dipanggil, maka itu sama sekali bukan kebocoran.
nsayer
Amiga DOS adalah O / SI terakhir yang tidak membersihkan proses. Berhati-hatilah, bahwa memori bersama Sistem V IPC dapat ditinggalkan meskipun tidak ada proses yang menggunakannya.
Jonathan Leffler
Palm tidak membebaskan memori "bocor" sampai Anda hotsync. datang setelah amiga. Saya sudah menjalankan aplikasi di emulator telapak tangan saya yang bocor .. Mereka tidak pernah sampai ke telapak tangan saya yang sebenarnya.
baash05
6

ini sangat spesifik domain sehingga hampir tidak layak dijawab. gunakan kepalamu yang menakutkan.

  • sistem operasi luar angkasa: tidak, tidak ada kebocoran memori yang diperbolehkan
  • kode proof-of-concept pengembangan cepat: memperbaiki semua kebocoran memori adalah buang-buang waktu.

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.

Dustin Getz
sumber
2
Sikapnya sangat picik. Anda pada dasarnya mengatakan bahwa tidak perlu menggunakan praktik pemrograman yang fundamental sampai ada kerusakan yang disebabkan oleh praktik tersebut. Masalahnya adalah bahwa perangkat lunak yang ditulis menggunakan metode ceroboh cenderung memiliki lebih banyak cacat daripada perangkat lunak yang tidak.
John Dibling
1
Saya tidak percaya itu semua. Dan manajemen memori lebih rumit daripada menulis metode bersih.
Dustin Getz
1
Dustin jelas bekerja di dunia nyata seperti kebanyakan dari kita, di mana kita terus bekerja melawan tenggat waktu gila untuk mengikuti kompetisi. Jadi berurusan dengan bug harus dilakukan secara pragmatis. Dengan membuang terlalu banyak waktu untuk bug yang tidak penting dalam program yang tidak penting, Anda tidak akan menyelesaikan pekerjaan Anda.
Wouter van Nifterick
Masalah dengan sikap ini adalah: kapan Anda mulai memperbaiki kebocoran? "OK, itu pembangkit listrik, tapi itu hanya batu bara, bukan Uranium. Mengapa memperbaiki kebocoran di sini?" - Saya belajar di dunia nyata bahwa jika Anda tidak melakukan hal yang benar sejak awal, sepanjang waktu, itu tidak pernah terjadi. Sikap itu melahirkan proyek yang "99% selesai" setelah dua minggu dan tetap demikian selama dua bulan.
peterchen
5

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%.

John Dibling
sumber
5

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.

Louis Gerbarg
sumber
Pintar. Terutama karena kebocoran itu selama inisialisasi, yang berarti bahwa itu tidak akan terakumulasi selama runtime aplikasi.
Demi
5

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:

Bagaimana jika Anda mengalokasikan sebagian memori dan menggunakannya hingga baris terakhir kode dalam aplikasi Anda (misalnya, dekonstruktor 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.

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 kebocoranFILE 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.

Blaisorblade
sumber
Wow ... seseorang yang tahu apa kebocoran memori itu.
Simon Buchan
4

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

  1. Untuk perangkat lunak Anda dan pengalaman pengguna Anda.
  2. Untuk sistem (dan pengguna) dalam hal hemat dengan sumber daya sistem.
  3. Dampak perbaikan pada pemeliharaan dan keandalan.
  4. Kemungkinan menyebabkan regresi di tempat lain.

Foredecker

Foredecker
sumber
3. Dampak pada pemeliharaan perangkat lunak.
peterchen
3

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!

Ather
sumber
3

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
3

Saya kira tidak apa-apa jika Anda menulis sebuah program yang dimaksudkan untuk membocorkan memori (yaitu untuk menguji dampak kebocoran memori pada kinerja sistem).

Bip bip
sumber
3

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.

Komponen 10
sumber
2

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.

Sanjaya R
sumber
2

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.

Corey Trager
sumber
2

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.

tloach
sumber
Dalam hal ini dampak kebocoran memori berubah, dan Anda perlu mengevaluasi kembali prioritas memasang kebocoran.
John Dibling
@ John: Anda sebaiknya mendokumentasikan kebocoran itu. Meski begitu, saya tidak akan mempercayai seseorang untuk tidak mengabaikan komentar berkedip merah besar dan copy-paste paste kode bocor Saya lebih suka untuk tidak memberi seseorang kemampuan untuk melakukan itu sejak awal.
tloach
2

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.

Konrad Rudolph
sumber
2

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.

alas tiang
sumber
2

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?

Dima
sumber
Tetapi jika Anda memiliki mobil dengan mesin yang sesekali bocor oli, apakah Anda mengeluarkan uang untuk memperbaikinya, atau apakah Anda mengawasi level oli dan menambahnya dari waktu ke waktu. Jawabannya tergantung pada semua jenis faktor.
langsing
Ini bukan tentang memiliki mobil. Ini tentang membangun mobil. Jika Anda mendapatkan perpustakaan pihak ketiga dengan kebocoran memori dan Anda benar-benar harus menggunakannya, maka Anda bisa menggunakannya. Tetapi jika Anda yang menulis sistem atau pustaka, Anda bertanggung jawab untuk memastikannya bebas bug.
Dima
+1 perlakukan itu seperti bug lainnya. (Itu tidak berarti "perbaiki secara instan" dalam buku saya, tetapi "harus diperbaiki" untuk memastikan)
peterchen
2

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.

EvilTeach
sumber
Saya telah bekerja pada program server yang sengaja menggunakan proses daripada utas, sehingga kebocoran memori dan kesalahan segmentasi menyebabkan kerusakan terbatas.
langsing
Pendekatan yang menarik. Saya akan sedikit khawatir tentang proses yang gagal keluar dan terus melahap memori.
EvilTeach
2

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.

Enno
sumber