Bellek sızıntıları hiç iyi mi? [kapalı]


231

C veya C ++ uygulamanızda bellek sızıntısı olması hiç kabul edilebilir mi?

Bir bellek ayırır ve uygulamanızdaki en son kod satırına kadar kullanırsanız (örneğin, bir global nesnenin yıkıcısı)? Bellek tüketimi zaman içinde artmadığı sürece, uygulamanız sona erdiğinde (Windows, Mac ve Linux'ta) işletim sisteminin belleğinizi boşaltmasına güvenmek uygun mudur? Bellek, işletim sistemi tarafından serbest bırakılana kadar sürekli olarak kullanılıyorsa, bunun gerçek bir bellek sızıntısı olduğunu düşünür müsünüz?

Bir üçüncü taraf kütüphanesi bu durumu sizin için zorlarsa ne olur? Aksi ne kadar büyük olursa olsun bu üçüncü taraf kütüphanesini kullanmayı reddeder misiniz?

Sadece bir pratik dezavantaj görüyorum ve bu iyi huylu sızıntıların yanlış sızıntı olarak bellek sızıntısı algılama araçlarıyla ortaya çıkacağıdır.


50
Bellek tüketimi zaman içinde artmazsa, bir sızıntı değildir.
mpez0

4
Çoğu uygulama (tüm .NET programları dahil) en az birkaç arabellek içerir ve bir kez ayrılır ve hiçbir zaman açıkça serbest bırakılmaz. Bu nedenle mpez0'ın tanımı daha kullanışlıdır.
Ben Voigt

2
Evet, sonsuz hafızanız varsa.
kullanıcı

"İyi huylu" bir sızıntı (böyle bir şey varsa) yanlış bir pozitif değildir - çok doğru bir şekilde tespit edilen bir sızıntıdır. Sızıntı tespiti, kişisel olarak tamir etmek istemediğiniz sızıntılar için bile, bir sızıntı detektörünün mevcut nedenidir.
cHao

1
@ mpez0 "Bellek tüketimi zamanla artmazsa, bir sızıntı olmaz"? Bu bir bellek sızıntısının tanımı değil. Bir sızıntı, sızan hafızadır, yani serbest bırakılmadı ve artık referansınız yok, bu yüzden tekrar özgür bırakmanız imkansız. Büyümek veya büyümemek önemsizdir.
Mecki

Yanıtlar:


329

Hayır.

Profesyoneller olarak kendimize sormamamız gereken soru, "Bunu yapmak hiç sorun değil mi?" daha ziyade " Bunu yapmak için iyi bir neden var mı ?" Ve "bu hafıza sızıntısını avlamak bir acıdır" iyi bir sebep değildir.

Ben işleri basit tutmayı severim. Ve basit kural, programımın bellek sızıntısı olmaması gerektiğidir.

Bu da hayatımı kolaylaştırıyor. Bir bellek sızıntısı tespit edersem, "kabul edilebilir" bir bellek sızıntısı olup olmadığını belirlemek için bazı ayrıntılı karar ağacı yapısından geçmek yerine onu ortadan kaldırırım.

Derleyici uyarılarına benzer - uyarısı özel uygulamam için ölümcül olacak mı? Belki de değil.

Ama sonuçta profesyonel bir disiplin meselesi. Derleyici uyarılarını tolere etmek ve bellek sızıntılarını tolere etmek kötü bir alışkanlıktır.

İşleri aşırı bir noktaya götürmek için, bir cerrahın hastanın içinde bir takım ameliyat ekipmanı bırakması kabul edilebilir mi?

SurgeonOverflow.com'da yayınlanan bu soruyu görürsem, o ekipman parçasını çıkarmanın maliyetinin / riskinin onu bırakma maliyetini / riskini aştığı bir durum ortaya çıkabilir ve zararsız olduğu durumlar olabilir. ve "hayır" dışında herhangi bir cevap gördüm. Bu, tıp mesleğine olan güvenimi ciddi şekilde zayıflatacaktır.

-

Üçüncü taraf bir kütüphane bu durumu üzerimde zorladıysa, söz konusu kütüphanenin genel kalitesinden ciddi şekilde şüphelenmeme neden olur. Test, bir araba sürdüm ve bardak tutuculardan birinde birkaç gevşek pul ve somun buldum - kendi başına büyük bir şey olmayabilir, ancak kaliteye bağlılık eksikliğini tasvir ediyor, bu yüzden alternatifleri düşünürdüm.


57
Doğru ve aynı zamanda doğru değil. Çoğumuz ücret köleleriyiz ve her türlü işçilik arzusu işin gereksinimlerine arka koltuk almalıdır. Bu üçüncü taraf kütüphanesinde bir sızıntı varsa ve 2 hafta iş tasarrufu sağlıyorsa, bunu kullanmak için bir iş vakası olabilir, vb.
Cervo

3
Zaten ihtiyacım olan bir şey olsaydı ve iyi alternatifler olmasaydı kütüphaneyi yine de kullanırdım, ancak koruyucularla bir hata kaydederdim.
20'de tloach

7
Ben şahsen aynı cevapla giderken, hafızayı neredeyse hiç boşta bırakmayan programlar var. Bunun nedeni, a) boş bellek kullanan işletim sistemlerinde çalıştırılması amaçlanan ve b) çok uzun süre çalışmayacak şekilde tasarlanmış olmalarıdır. Bir program için nadiren kısıtlamalar var, ancak bunu kesinlikle geçerli olarak kabul ediyorum.

2
Erken kontrol için bazı nedenler eklemek için: hata ayıklama araçlarınız "iyi huylu" sızıntılara maruz kaldığında, "gerçek" olanı nasıl bulacaksınız? Bir toplu işlem özelliği eklerseniz ve aniden 1K / saat sızıntınız 1K / saniye olur mu?
peterchen

5
Hmm "bellek sızdırmıyor" "mükemmel" mi?
JohnMcG

80

"Kullanılan" bellek miktarı artmaya devam etmedikçe bunun bir bellek sızıntısı olduğunu düşünmüyorum. Yeterli olmasa da, yayınlanmamış bir belleğe sahip olmak, gerekli bellek miktarı büyümeye devam etmedikçe büyük bir sorun değildir.


12
Teknik olarak, bir sızıntı tahsis edilen bellektir ve buna yapılan tüm referanslar kaybolur. Sonunda hafızanın yerini değiştirmemek tembeldir.
Martin York

17
1 GB'lik 1 kez bellek sızıntısı varsa, bu bir sorundur.
John Dibling

21
Büyümek ya da büyümemek önemli değil. Başka programlar ayırdıysanız belleği kullanamaz.
Kertenkele Bill

8
> Başka programlar ayırdıysanız belleği kullanamaz. İşletim sistemi her zaman belleğinizi diske değiştirebilir ve diğer uygulamaların yararlanamayacağınız RAM'i kullanmasına izin verebilir.
Max Lybbert

4
Program çok kısa ömürlü ise, bir sızıntı o kadar da kötü olmayabilir. Ayrıca, ideal DEĞİL olsa da, sayfalama burada bazıları kadar pahalı değildir, çünkü program bu hafıza ile ilgilenmez (Ve böylece her zaman takas olmaz) - tabii ki, bir GC ...
Arafangion

79

Önce tanımlarımızı doğru yapalım. Bellek sızıntısı , bellek dinamik olarak tahsis edildiğinde, örn. İle malloc()ve belleğe yapılan tüm referanslar, karşılık gelen boş alan olmadan kaybolur. Bunu yapmanın kolay bir yolu şöyledir:

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

While (1) döngüsünde her seferinde 1024 (+ havai) baytın atandığını ve vp'ye yeni adresin atandığını unutmayın. önceki hatalı bloklara kalan işaretçi yok. Bu program, yığın bitene kadar çalışacak şekilde garanti edilir ve hatalı belleğin herhangi birini kurtarmanın bir yolu yoktur. Bellek bir daha asla görülmeyecek şekilde öbekten "sızıyor".

Açıkladığınız şey kulağa hoş geliyor

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

Belleği ayırırsınız, program sona erene kadar onunla birlikte çalışırsınız. Bu bir bellek sızıntısı değil ; programı bozmaz ve program sona erdiğinde tüm bellek otomatik olarak silinir.

Genellikle bellek sızıntılarından kaçınmalısınız. Birincisi, üstünüzdeki rakım ve hangarda yakıt kullanmak gibi, sızan ve kurtarılamayan bellek işe yaramaz; ikinci olarak, doğru şekilde kodlamak, bellek sızıntısı yapmak değil, başlangıçta daha sonra bellek sızıntısı bulmaktan çok daha kolaydır.


Şimdi bu tahsisleri birkaç düzine düşünün. Şimdi "ana" gövdeyi birden çok kez çağrılan rutine taşımayı düşünün. Zevk almak. - Bu senaryoda bu kadar büyük bir sorun olmadığı fikrine katılıyorum, ancak senaryolar değişiyor. Dedikleri gibi, her zaman kodu bakacak kişi nerede yaşadığını biliyormuş gibi yaz.
peterchen

2
Mesele şu ki, program _exit () çağrılıncaya kadar yanlış yerleştirilmiş ve tutulan bellek "sızdırılmaz".
Charlie Martin

1
Bu bir bellek sızıntısıdır ve programınızı bozabilir. Gelecekteki tahsisler bu süreçten başarısız olabilir, çünkü eminim ki malloc her yerde sıfır olmayan bir şekilde geri döndü. hafızanın az olduğu gömülü bir durumda olduğu gibi hafızayı aşırı kullanarak bu yaşam ve ölüm arasındaki fark olabilir.
MikeJ

10
Mike, bu doğru değil. Uyumlu bir C ortamında, main'i sonlandırmak tüm işlem kaynaklarını serbest bırakır. Açıkladığınız gibi gömülü bir ortamda, bu durumu görebilirsiniz, ancak bir ana hattınız olmazdı. Şimdi, bunun doğru olmayacağı kusurlu gömülü ortamlar olabileceğini söyleyeceğim, ancak sonra + = ile doğru bir şekilde başa çıkamayan kusurlu ortamlar gördüm.
Charlie Martin

3
Evet, artık mallocçok fazla hafızaya sahipseniz bunun Kötü Bir Şey olduğunu keşfettiniz . Hala bir sızıntı değil . Referansın kaybolduğu hafızaya kadar ve kaçak olmaz malloc.
Charlie Martin

39

Teori No, pratikte bunun bağlıdır .

Bu gerçekten programın ne kadar veri üzerinde çalıştığına, programın ne sıklıkta çalıştığına ve sürekli çalışıp çalışmadığına bağlıdır.

Küçük miktarda veri okuyan ve hesaplama yapan hızlı bir programım varsa, küçük bir bellek sızıntısı fark edilmez. Program çok uzun süre çalışmadığı ve yalnızca az miktarda bellek kullandığı için, program olduğunda sızıntı küçük olacak ve serbest kalacaktır.

Öte yandan, milyonlarca kaydı işleyen ve uzun süre çalışan bir programım varsa, küçük bir bellek sızıntısı makineyi yeterli süre verebilir.

Sızıntı olan üçüncü taraf kitaplıklara gelince, bir soruna neden olurlarsa ya kitaplığı düzeltin ya da daha iyi bir alternatif bulun. Eğer bir soruna neden olmazsa, gerçekten önemli mi?


Bütün sorumu okuyup okumadığınızı bilmiyorum. Belleğin uygulamanın sonuna kadar kullanıldığını söylüyorum. Zamanla büyümez. Tek hayır, serbest / silme çağrısı olmamasıdır.
Imbue

2
O zaman bu gerçekten bir bellek sızıntısı değil. Bellek sızıntısı az miktarda kullanılmamış ancak serbest bırakılmış bellektir, bu miktar zamanla artar. Bahsettiğiniz şey bir bellek damlasıdır. Damlacık çok büyük olmadığı sürece bununla ilgilenmeyin.
vfilby

"Eğer bir soruna neden olmazsa, gerçekten önemli mi?" Hayır, hiç önemli değil. Keşke daha çok insan dindar olmak yerine bunu elde etsin.
Imbue

2
@John: Bu genellikle tembel geliştiriciler ve daha çok yazılım geliştirme meselesi. Hepimiz hata yaparız, hatalar bizim ticaretimizdir; Onları düzeltmemizi sağlıyoruz, biz de bunu yapıyoruz. Her zaman açık maliyet ile uzun vadeli bakım arasında bir denge vardır, bu denge asla doğrudan değildir.
vfilby

1
John,% 100 sana katılıyorum .. Imbum Soru neredeyse, "ne kadar kabul ediyorsun". Özensiz özensiz .. Monitörünün arkasında bir karides bırakmaya ne dersin. kıyameti kıyameti. Her mağaramızda, endüstrimiz biraz mağara yapar. Bir sızıntı olduğunu biliyorsanız ve buna neden olduğunu biliyorsanız, düzeltmeniz gerekir.
190

37

Birçok kişi belleği boşalttığınızda, anında işletim sistemine geri döndüğü ve diğer programlar tarafından kullanılabileceği izlenimi altında görünüyor.

Bu doğru değil. İşletim sistemleri genellikle 4KiB sayfalarındaki belleği yönetir. mallocve diğer bellek yönetimi sayfalarını işletim sisteminden alır ve uygun gördükleri şekilde alt yönetir. Oldukça olasılıklar söz konusudur free()olacak değil Programınız sonra daha fazla bellek malloc'dan olacağı varsayımıyla, işletim sistemine sayfaları getirir.

Bunu söylemiyorum free() hiçbir zaman işletim sistemine bellek döndürmediğini . Bu, özellikle büyük miktarda bellek boşaltıyorsanız, olabilir. Ama garanti yok.

Önemli gerçek: Artık ihtiyaç duymadığınız belleği boşaltmazsanız, daha fazla mallokun daha fazla tüketmesi garanti edilir bellek . Ama önce boşta kalırsanız, malloc serbest belleği yeniden kullanabilir.

Bu pratikte ne anlama geliyor? Bu, programınızın bundan sonra daha fazla bellek gerektirmeyeceğini biliyorsanız (örneğin, temizleme aşamasındadır), belleği boşaltmak o kadar önemli değildir. Ancak, program daha sonra daha fazla bellek ayırabilirse, bellek sızıntılarından kaçınmalısınız - özellikle de tekrar tekrar meydana gelebilecek olanlardan.

Ayrıca bu yoruma bakın , sonlandırmadan hemen önce belleği boşaltmanın neden kötü olduğu hakkında daha fazla ayrıntı için .

Bir yorumcu aramanın free() diğer programların serbest bırakılmış belleği kullanmasına otomatik olarak izin vermediğini . Ama bu cevabın bütün mesele bu!

Yani, insanları ikna etmek için, free () 'in çok az işe yaradığı bir örnek göstereceğim. Matematiği takip etmeyi kolaylaştırmak için, işletim sisteminin 4000 baytlık sayfalarda belleği yönettiğini iddia edeceğim.

On bin 100 baytlık blok tahsis ettiğinizi varsayalım (basitlik için bu tahsisleri yönetmek için gereken ekstra belleği göz ardı edeceğim). Bu 1MB veya 250 sayfa tüketir. Daha sonra bu blokların 9000'ini rastgele serbest bırakırsanız, sadece 1000 blokla kalırsınız - ancak her yere dağılmışlardır. İstatistiksel olarak, sayfaların yaklaşık 5'i boş olacaktır. Diğer 245'ün her birinde en az bir ayrılmış blok bulunur. Bu, yalnızca 100KB tahsis edilmiş olsanız bile, işletim sistemi tarafından geri alınamayan 980KB bellek demektir!

Öte yandan, artık programınızın bağladığı bellek miktarını artırmadan 9000 blok daha malloc () edebilirsiniz.

Bile free()olabilir teknik olarak OS hafızayı dönmek, bunu yapmak olmayabilir. free()hızlı çalışma ve bellek tasarrufu arasında bir denge kurması gerekir. Ayrıca, çok fazla bellek ayıran ve daha sonra serbest bırakan bir programın bunu tekrar yapması muhtemeldir. Bir web sunucusunun istek sonrasında istek sonrasında işlem yapması gerekir - işletim sisteminden her zaman bellek istemeniz gerekmez.


1
Ya diğer programlar, programınızın gereksiz yere tuttuğu belleği gerektiriyorsa, daha fazla malloca ihtiyacınız olmasa bile, kullanılmayan bellek alanlarını serbest bırakın () :)
MN

2
Demek istediğimi tamamen kaçırdın. Belleği boşalttığınızda (), diğer programlar belleği kullanamaz !! (Bazen, özellikle büyük bellek bloklarını serbest bırakırsanız yapabilirler. Ama çoğu zaman yapamazlar!) Bunu daha net hale getirmek için yazımı düzenleyeceğim.
Artelius

27

Uygulama çalıştırıldıktan sonra işletim sisteminin temizlenmesi ile ilgili kavramsal olarak yanlış bir şey yoktur.

Bu gerçekten uygulamaya ve nasıl çalıştırılacağına bağlıdır. Haftalarca çalışması gereken bir uygulamada sürekli olarak meydana gelen sızıntılara dikkat edilmesi gerekir, ancak çok yüksek bir bellek ihtiyacı olmadan bir sonucu hesaplayan küçük bir araç sorun olmamalıdır.

Birçok betik dilinin çöp çevrimsel olarak toplanmamasının bir nedeni vardır ... kullanım kalıpları için bu gerçek bir sorun değildir ve bu nedenle boşa giden bellek kadar kaynak israfı olacaktır.


Komut dosyası oluşturma dilleri hakkında: Python yeniden sayım kullanır, ancak yalnızca çevrimsel referansları serbest bırakmak için bir GC'ye sahiptir. Diğer dillerde, programcı genellikle açıkça döngüsel referanslardan tamamen kaçınır ve bu da başka problemler yaratır.
Blaisorblade

PHP'nin önceki sürümleri belleği serbest bırakmadı, başlangıçtan sonuna kadar bellekte büyüdüler - tipik olarak 0.1 saniyelik yürütme süresinden sonra komut dosyası çıkacak ve tüm bellek geri kazanılacaktı.
Arafangion

19

Cevabın hayır olduğuna inanıyorum, asla bellek sızıntısına izin vermeyin ve açıkça belirtmediğim birkaç nedenim var. Burada harika teknik cevaplar var ama bence asıl cevap daha çok sosyal / insani nedenlere bağlı.

(Öncelikle, diğerlerinin de belirttiği gibi, gerçek bir sızıntı, programınızın herhangi bir noktada tahsis ettiği bellek kaynaklarının izini kaybettiğini unutmayın. C'de, malloc()bir işaretçiye gittiğinizde ve bu işaretçinin,free() ilk.)

Buradaki kararınızın önemli noktası alışkanlıktır. İşaretçileri kullanan bir dilde kod yazdığınızda, işaretçileri çok kullanacaksınız . Ve işaretçiler tehlikelidir; kodunuza her türlü ciddi sorunu eklemenin en kolay yoludur.

Kod yazarken bazen topun üzerinde, bazen de yorgun, kızgın veya endişeli olursunuz. Dikkat dağıtan bu zamanlarda, otomatik pilotta daha fazla kod yazıyorsunuz. Otopilot etkisi, bir kerelik kod ile daha büyük bir projedeki bir modül arasında ayrım yapmaz. Bu zamanlarda, kurduğunuz alışkanlıklar kod tabanınızda ortaya çıkacak olan şeylerdir.

Yani hayır, şu anda yolda tek araba olsanız bile şerit değiştirirken kör noktalarınızı kontrol etmelisiniz. Aktif beyninizin dikkati dağıldığı zamanlarda, sizi felaketle ilgili yanlış adımlardan kurtarabilecek iyi alışkanlıklar vardır.

"Alışkanlık" sorunun ötesinde, işaretçiler karmaşıktır ve zihinsel olarak izlemek için çok fazla beyin gücü gerektirir. İşaretçileri kullanımınız söz konusu olduğunda, özellikle de programlamaya yeni başladığınızda "suyu çamurlamamak" en iyisidir.

Daha sosyal bir yönü de var. Kodunuzu doğru şekilde kullanan malloc()ve free()kodunuza bakan herkes rahat olacaktır; kaynaklarınızı yönetiyorsunuz. Ancak bunu yapmazsanız, derhal bir sorundan şüpheleneceklerdir.

Belki de bellek sızıntısının bu bağlamda hiçbir şeye zarar vermediğini fark ettiniz, ancak kodunuzun her bir koruyucusu bu kod parçasını okuduğunda da kafasında çalışmak zorunda kalacak. Kullanarak free()sorunu bile dikkate alma ihtiyacını ortadan kaldırırsınız.

Son olarak, programlama bir sürecin zihinsel bir modelini açık bir dile yazıyor, böylece bir kişi ve bir bilgisayar söz konusu süreci mükemmel bir şekilde anlayabiliyor. İyi programlama uygulamasının hayati bir parçası, asla gereksiz belirsizlik getirmektir.

Akıllı programlama esnek ve geneldir. Kötü programlama belirsizdir.


Alışkanlık fikrini seviyorum. Ben de katılıyorum. Bir bellek sızıntısı görürsem, kodlayıcının başka hangi köşeyi kestiğini her zaman merak ederim. Özellikle
belliyse

Bu en iyi cevap. 5 yıldır C ++ 'da program yapıyorum ve hiçbir zaman tek bir bellek sızıntısı yazmadım. Sebebi ben bellek sızıntısı eğilimindedir kod yazmak değil. İyi C ++ tasarımı nadiren kullanır new, böylece çoğu bellek sızıntısını hemen ortadan kaldırır. Sadece mutlaka kullanmanız gerekiyorsa new. Bunun sonucu newhemen akıllı bir işaretçiye yerleştirilmelidir. Bu iki kurala uyarsanız, asla bellek sızıntısı yapmazsınız (kitaplıktaki bir hatayı engeller). Geriye kalan tek durum shared_ptrdöngüdür, bu durumda kullanmayı bilmeniz gerekir weak_ptr.
David Stone

15

Bence sizin durumunuzda bu sorunun cevabı iyi olabilir. Ancak kesinlikle bellek sızıntısının bilinçli bir karar olduğunu belgelemeniz gerekir. Bir bakım programcısının gelmesini, kodunuzu bir işlevin içine atmasını ve milyonlarca kez çağırmasını istemezsiniz. Bu nedenle, bir sızıntının uygun olduğuna karar verirseniz, gelecekte program üzerinde çalışmak zorunda kalabilecekler için belgeyi (BÜYÜK MEKTUPLARDA) belgelemeniz gerekir.

Bu üçüncü taraf bir kütüphane ise tuzağa düşmüş olabilirsiniz. Ama kesinlikle bu sızıntının meydana geldiğini belgeleyin.

Ancak temelde bellek sızıntısı 512 KB'lik bir tampon gibi bilinen bir miktarsa, o zaman sorun değildir. Bir kütüphane çağrısını her aradığınızda bellek sızıntısı büyümeye devam ederse, belleğiniz 512 KB artar ve serbest bırakılmazsa, bir sorun yaşayabilirsiniz. Belgeyi belgelerseniz ve aramanın kaç kez yürütüldüğünü kontrol ederseniz, yönetilebilir olabilir. Ama o zaman gerçekten belgelere ihtiyacınız var çünkü 512 çok olmasa da, bir milyondan fazla çağrı çok fazla.

Ayrıca işletim sistemi belgelerinizi de kontrol etmeniz gerekir. Bu, gömülü bir aygıtsa, çıkmakta olan bir programdan tüm belleği boşaltmayan işletim sistemleri olabilir. Emin değilim, belki bu doğru değil. Ama içine bakmaya değer.


3
"Ama kesinlikle bellek sızıntısının bilinçli bir karar olduğunu belgelemeniz gerekiyor." Şükürler olsun. Şimdiye kadar yapılan en iyi nokta.
pestophagous

15

Programın bellek kullanımını azaltacağı sürece belleği boşaltmanın her zaman yanlış olduğuna dair popüler olmayan ama pratik bir cevap vereceğim . Örneğin, tüm ömrü boyunca kullanacağı veri kümesini yüklemek için tek bir ayırma veya ayırma dizisi yapan bir programın herhangi bir şey boşaltmasına gerek yoktur. Çok dinamik bellek gereksinimlerine sahip büyük bir programın daha yaygın olduğu durumda (bir web tarayıcısı düşünün), artık kullanmadığınız belleği olabildiğince çabuk boşaltmalısınız (örneğin, bir sekmeyi / belgeyi / vb. Kapatma). , ancak kullanıcı "çıkış" ı tıklamayı seçtiğinde hiçbir şeyi boşaltmak için hiçbir neden yoktur ve bunu yapmak kullanıcı deneyimine gerçekten zarar verir.

Neden? Hafızada yer açmak hafızaya dokunmayı gerektirir. Sisteminizin malloc uygulaması, tahsis edilen bellek bloklarına bitişik meta verileri depolamasa bile, muhtemelen ücretsiz olarak ihtiyacınız olan tüm işaretçileri bulmak için özyinelemeli yapılar yürüyor olacaksınız.

Şimdi, programınızın büyük miktarda veriyle çalıştığını, ancak bir süredir çoğuna dokunmadığını varsayalım (yine, web tarayıcısı harika bir örnektir). Kullanıcı çok sayıda uygulama çalıştırıyorsa, bu verilerin büyük bir kısmı diske değiştirilmiş olabilir. Sadece (0) 'dan çıkarsanız veya ana menüden dönerseniz, hemen çıkar. Mükemmel kullanıcı deneyimi. Her şeyi serbest bırakma sorununa giderseniz, tüm verileri geri takas etmek için 5 saniye veya daha fazla zaman harcayabilirsiniz, sadece bundan hemen sonra atmak için. Kullanıcının zaman kaybı. Dizüstü bilgisayarın pil ömrünün israfı. Sabit diskte aşınma kaybı.

Bu sadece teorik değil. Kendimi çok fazla uygulama yüklendiğinde bulduğumda ve disk çökmeye başladığında, "çıkış" ı tıklamayı düşünmüyorum bile. Ben olabildiğince hızlı bir terminale almak ve killall -9 yazın ... çünkü "çıkış" sadece daha da kötüleştireceğini biliyorum.


5
Raymond Chen'den bu alıntıya bayılıyorum: "Bina yıkılıyor. Zemini süpürüp çöp kutularını boşaltmak ve yazı tahtalarını silmek zahmetine girmeyin. Ve binanın çıkışında herkesin Yaptığın tek şey yıkım ekibinin bu anlamsız ev temizliği işini bitirmeni beklemesini sağlamak. " ( blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683 )
Andreas Magnusson

11

Eminim birileri Evet demek için bir neden bulabilir, ama bu ben olmayacağım. Hayır demek yerine, bunun evet / hayır sorusu olmaması gerektiğini söyleyeceğim. Bellek sızıntılarını yönetmenin veya içermenin yolları vardır ve birçok sistemde bunlara sahiptir.

Bunun için dünyayı terk eden cihazlarda NASA sistemleri var. Sistemler otomatik olarak sık sık yeniden başlatılır, böylece bellek sızıntıları genel işlem için ölümcül olmaz. Sadece bir sınırlama örneği.


Bu aslında yazılımın yaşlanmasına bir örnek. Büyüleyici çalışma konusu.
Konrad Rudolph

Sık sık otomatik olarak yeniden başlatma, ha? NASA, ha? (* eski Microsoft Windows kurulum CD'lerine bakar *) Bu çok açıklıyor ...
Christian Severin

8

Belleği ayırır ve programınızın son satırına kadar kullanırsanız, bu bir sızıntı değildir. Belleği ayırır ve unutursanız, bellek miktarı artmasa bile, bu bir sorundur. Ayrılan ancak kullanılmayan bellek, diğer programların daha yavaş çalışmasına veya hiç çalışmamasına neden olabilir.


Gerçekten değil, çünkü kullanılmazsa, sadece sayfalanacaktır. Uygulamadan çıkıldığında tüm bellek serbest bırakılır.
Eclipse

Tahsis edildiği sürece diğer programlar onu kullanamaz. Yeniden konumlandırmazsanız sayfalandırılmaz.
Kertenkele Bill

Tabii ki olacak - sanal bellek bununla ilgili. 1 GB gerçek RAM'e sahip olabilirsiniz ve yine de her biri 2 GB sanal bellek ayıran 4 işleminiz olabilir (sayfa dosyanız yeterince büyük olduğu sürece).
Eclipse

Tabii ki, eğer bu süreçlerin her biri aktif olarak tüm hafızayı kullanıyorsa, kötü çağrı sorunları yaşayacaksınız.
Eclipse

Tamam, şimdi neden bahsettiğinizi anlıyorum. Kullanmadığınız belleği yeniden ayırırsanız, disk belleği gereksinimini azaltırsınız. Ayrılmaya devam ederseniz, başvurunuz geri çağrıldığında yine de saklar.
Kertenkele Bill

8

Bir yandan zamanla gördüğüm "iyi huylu" sızıntıların sayısını sayabilirim.

Bu yüzden cevap çok nitelikli bir evet.

Bir örnek. Dairesel bir kuyruğu veya deque'yi depolamak için bir tampona ihtiyaç duyan ancak tamponun ne kadar büyük olması gerektiğini bilmeyen ve kilitleme yükünün veya her okuyucunun yükünü karşılayamayacak tek bir kaynağınız varsa, daha sonra katlanarak iki katına çıkan bir tampon tahsis eder, ancak eskilerini serbest bırakmamak sıra / deque başına sınırlı miktarda bellek sızdırır. Bunun yararı, her erişimi dramatik bir şekilde hızlandırması ve bir kilit için çekişme riski olmadan çok işlemcili çözümlerin asimptotiklerini değiştirebilmeleridir.

Bu yaklaşımın CPU başına iş çalma deques gibi çok açık bir şekilde sabit sayılan şeylere büyük fayda sağlamak için kullanıldığını /proc/self/mapsve Hans Boehm'in C / C ++, kök kümelerini algılamak için kullanılır.

Teknik olarak bir sızıntı olsa da, bu iki durumun boyutu sınırlıdır ve büyüyebilen dairesel iş çalma deque durumunda , kuyruklar için bellek kullanımında 2'lik sınırlı bir faktör karşılığında büyük bir performans kazancı vardır.


1
Sızıntıyı önlemek için tehlike işaretçileri kullanabilirsiniz.
Demi

8

Programınızın başında bir yığın yığın ayırırsanız ve çıktığınızda serbest bırakmazsanız, bu bir bellek sızıntısı değildir. Bellek sızıntısı, programınızın kodun bir bölümü üzerinde döngü yapması ve bu kodun yığın ayırması ve serbest bırakmadan "izini" kaybetmesidir.

Aslında, çıkmadan hemen önce free () veya delete çağrıları yapmanıza gerek yoktur. İşlem sona erdiğinde, tüm belleği işletim sistemi tarafından geri kazanılır (bu kesinlikle POSIX için geçerlidir. Diğer işletim sistemlerinde - özellikle gömülü olanlarda - YMMV).

Çıkış zamanında hafızayı boşaltmamaya dair tek uyarı, programınızı yeniden düzenlerseniz, örneğin, girdiyi bekleyen bir hizmet haline gelir, programınız ne yaparsa yapın, sonra beklemek için etrafta dolaşır. başka bir servis çağrısı yaparsanız, kodladığınız şey bellek sızıntısına dönüşebilir.


Naçizane size katılmıyorum. Yani bir “bellek sızıntısı haddi zatında”.
Konrad Rudolph

Nesneye olan referansı "kaybeden" bir sızıntı değildir. Muhtemelen, bellek programın ömrü boyunca kullanılıyorsa, sızıntı yapmaz. Exit () çağrılıncaya kadar başvuru kaybolmazsa, kesinlikle bir sızıntı değildir .
nsayer

Amiga DOS, süreçlerin arkasını temizlemeyen son O / SI idi. Yine de, System V IPC paylaşılan belleğinin hiçbir işlem kullanmasa bile bırakılabileceğini unutmayın.
Jonathan Leffler

Palm size hotsync kadar bellek "sızdı" serbest. amiga'dan çok sonra geldi. Avuç içi emülatörümde sızıntı olan uygulamalar çalıştırdım .. Asla gerçek avucuma geçmediler.
190

6

bu, etki alanına özgüdür ve yanıtlamaya değmez. kafayı kullan.

  • uzay mekiği işletim sistemi: hayır, bellek sızıntısına izin verilmiyor
  • hızlı geliştirme konsept kanıtı: tüm bu bellek sızıntılarını düzeltmek zaman kaybıdır.

ve bir ara durum yelpazesi var.

en kötü bellek sızıntılarını düzeltmek için bir ürünün piyasaya sürülmesini ertelemenin fırsat maliyeti ($$$) genellikle "özensiz veya profesyonel olmayan" duygularını gölgede bırakır. Patronunuz size sıcak, bulanık duygular elde etmemek için para kazanmanızı öder.


2
Çok kısa görüşlü tutum. Temel olarak, bir kusurun bu uygulamalardan kaynaklandığı tespit edilene kadar temelde sağlam programlama uygulamalarının kullanılmasına gerek olmadığını söylüyorsunuz. Sorun, özensiz yöntemler kullanılarak yazılan yazılımın, olmayan yazılımlardan daha fazla kusura sahip olma eğilimindedir.
John Dibling

1
Hepsine inanmıyorum. Ve bellek yönetimi temiz yöntemler yazmaktan daha karmaşıktır.
Dustin Getz

1
Dustin açıkçası çoğumuz gibi gerçek dünyada çalışıyor ve rekabete ayak uydurmak için sürekli olarak son teslim tarihlerine karşı çalışıyoruz. Bu yüzden böceklerle uğraşmak pragmatik bir şekilde yapılmalıdır. Önemsiz programlarda önemsiz hatalara çok fazla zaman harcayarak, işlerinizi yapamazsınız.
Wouter van Nifterick

Bu tutumdaki sorun şudur: sızıntıları ne zaman düzeltmeye başlıyorsunuz? "Tamam, bu bir güç santrali, ama sadece kömür, Uranyum değil. Buradaki sızıntıları neden giderelim?" - Gerçek dünyada, doğru şeyi en baştan yapmazsanız, her zaman, asla gerçekleşmeyeceğini öğrendim. Bu tutum, iki hafta sonra "% 99 tamamlanmış" ve iki ay boyunca devam eden projeleri doğurur.
peterchen

5

Önce algılanan bellek sızıntısı ile gerçek bellek sızıntısı arasında büyük bir fark olduğunu fark etmelisiniz. Çok sık analiz araçları çok sayıda kırmızı ringa balığı rapor edecek ve sızdırılmadığı bir şeyi (bellek ya da tutamaç gibi kaynaklar) etiketlemeyecektir. Çoğu zaman bu, analiz aracının mimarisinden kaynaklanır. Örneğin, belirli analiz araçları çalışma zamanı nesnelerini bellek sızıntısı olarak rapor edecektir çünkü bu nesnenin asla serbest bırakılmadığını görecektir. Ancak, ayırma, analiz aracının göremeyeceği çalışma zamanının kapatma kodunda gerçekleşir.

Bununla birlikte, bulmak çok zor veya düzeltilmesi çok zor olan gerçek bellek sızıntılarına sahip olacağınız zamanlar olacaktır. Şimdi soru şu olur, kodda bırakmak hiç sorun değil mi?

İdeal cevap, "hayır, asla." Daha pragmatik bir cevap “hayır, neredeyse asla” olabilir. Çoğu zaman gerçek hayatta, çözmek için sınırlı sayıda kaynağınız ve zamanınız ve sonsuz görev listeniz vardır. Görevlerden biri bellek sızıntılarını ortadan kaldırdığında, azalan getiriler yasası çok sık devreye girer. Bir hafta içinde bir uygulamadaki tüm bellek sızıntılarının% 98'ini ortadan kaldırabilirsiniz, ancak kalan% 2'si aylar sürebilir. Bazı durumlarda, uygulamanın mimarisi nedeniyle belirli bir kodu yeniden düzenlemeden belirli sızıntıları ortadan kaldırmak bile imkansız olabilir. Kalan% 2'yi ortadan kaldırmanın maliyetlerini ve faydalarını tartmanız gerekir.


5

Bu tür bir soru bağlamında bağlam her şeydir. Şahsen sızıntılara dayanamıyorum ve kodumda, eğer onları kırpırlarsa düzeltmek için büyük uzunluklara gidiyorum, ancak bir sızıntıyı düzeltmek her zaman buna değmez ve insanlar zaman zaman bana ödeme yaptıkları zaman kodlarında bir sızıntıyı düzeltmem için ücretimin bana değmeyeceğini söyledi. Sana bir örnek vereyim:

Bir projeyi deniyordum, mükemmel işler yapıyordum ve birçok hatayı düzeltiyordum. Başvuruların başlatılması sırasında izlediğim ve tam olarak anladığım bir sızıntı vardı. Düzgün bir şekilde sabitlenmesi, bir parça işlevsel kodun bir gün kadar yeniden düzenlenmesi gerektirecektir. Ben hacky bir şey yapmış olabilir (bir küresel içine değer doldurma ve artık ücretsiz kullanımda olduğunu biliyorum bir nokta kapma gibi), ama bu sadece kod dokunmak zorunda sonraki adam için daha fazla karışıklığa neden olurdu.

Şahsen kodu ilk etapta bu şekilde yazmazdım, ama çoğumuz her zaman bozulmamış iyi tasarlanmış kod tabanları üzerinde çalışmaya başlamıyoruz ve bazen bu şeylere pragmatik olarak bakmak zorundasınız. 150 baytlık sızıntıyı düzeltmek için harcanacak zaman, bunun yerine megabaytlık koçlardan kurtulmak için algoritmik iyileştirmeler yapmak için harcanabilirdi.

Sonuçta, bir koç etrafında kullanılan ve adanmış bir makinede çalışan bir uygulama için 150 bayt sızmaya karar verdim, bu yüzden düzeltmeye değmez, bu yüzden sızdırıldığını, düzeltmek için neyin değiştirilmesi gerektiğini söyleyen bir yorum yazdım ve neden o zaman buna değmedi.


Akıllı. Özellikle sızıntı başlatma sırasında olduğu için, uygulamanın çalışma süresi boyunca birikmeyeceği anlamına gelir.
Demi

5

Çoğu cevap gerçek bellek sızıntılarına odaklanırken (bu hiç de iyi değil, özensiz kodlamanın bir işareti olduğu için), sorunun bu kısmı benim için daha ilginç görünüyor:

Bir bellek ayırır ve uygulamanızdaki en son kod satırına kadar kullanırsanız (örneğin, global bir nesnenin yapısökücüsü)? Bellek tüketimi zaman içinde artmadığı sürece, uygulamanız sona erdiğinde (Windows, Mac ve Linux'ta) işletim sisteminin belleğinizi boşaltmasına güvenmek uygun mudur? Bellek, işletim sistemi tarafından serbest bırakılana kadar sürekli olarak kullanılıyorsa, bunun gerçek bir bellek sızıntısı olduğunu düşünür müsünüz?

İlişkili bellek kullanılırsa, program bitmeden belleği boşaltamazsınız. Ücretsiz program çıkışı veya işletim sistemi tarafından yapılıp yapılmadığı önemli değildir. Bu belgelendiği sürece, değişiklik gerçek bellek sızıntılarına neden olmaz ve resimde C ++ yıkıcı veya C temizleme işlevi olmadığı sürece. Kapalı olmayan bir dosya sızdırılmış bir FILEnesne aracılığıyla açığa çıkabilir , ancak eksik bir fclose () ayrıca arabelleğin temizlenmemesine neden olabilir.

Yani, orijinal duruma geri dönersek, IMHO kendi içinde mükemmel bir şekilde tamam, o kadar ki en güçlü kaçak dedektörlerinden Valgrind, bu tür sızıntıları sadece talep edildiğinde tedavi edecek. Valgrind'da, bir işaretçiyi önceden serbest bırakmadan üzerine yazdığınızda, bellek sızıntısı olarak kabul edilir, çünkü tekrar olması ve yığının sonsuz büyümesine neden olması daha olasıdır.

Sonra, hala ulaşılabilir nfreed bellek blokları yoktur. Biri çıkışta hepsini serbest bırakabilir, ancak bu sadece kendi başına bir zaman kaybıdır. Onlar serbest edilip edilemeyeceğini noktasıdır önce . Bellek tüketimini azaltmak her durumda kullanışlıdır.


Vay be ... bellek sızıntısının ne olduğunu bilen biri.
Simon Buchan

4

Vfilby ile hemfikirim - duruma göre değişir. Windows'da, bellek sızıntılarını nispeten seröz hatalar olarak ele alıyoruz. Ancak, bu büyük ölçüde bileşene bağlıdır.

Örneğin, nadiren ve sınırlı sürelerle çalışan bileşenler için bellek sızıntıları çok ciddi değildir. Bu bileşenler çalışır, işleri yapar, sonra çıkar. Çıktıklarında tüm bellekleri dolaylı olarak boşaltılır.

Bununla birlikte, hizmetlerde veya diğer uzun süreli bileşenlerde (kabuk gibi) bellek sızıntıları çok ciddidir. Bunun nedeni, bu böceklerin zaman içinde hafızayı 'çalması'. Bunu kurtarmanın tek yolu bileşenleri yeniden başlatmaktır. Çoğu kişi bir hizmeti veya kabuğu nasıl yeniden başlatacağını bilmez - bu nedenle sistem performansları düşerse, yeniden başlatılır.

Yani, bir sızıntınız varsa - etkisini iki şekilde değerlendirin

  1. Yazılımınıza ve kullanıcı deneyiminize.
  2. Sistem kaynaklarına uygun olmaları açısından sisteme (ve kullanıcıya).
  3. Düzeltmenin bakım ve güvenilirlik üzerindeki etkisi.
  4. Başka bir yerde gerilemeye neden olma olasılığı.

Foredecker


3. Yazılımın bakımı üzerindeki etkisi.
peterchen

3

'Bilinen' bellek sızıntısının tahribat yaratmayacağından emin olsanız bile, bunu yapma. En iyi ihtimalle, farklı bir zamanda ve yerde benzer ve muhtemelen daha kritik bir hata yapmanın bir yolunu açacaktır.

Benim için bunu sormak "Kimsenin olmadığı sabah sabah saat 3'te kırmızı ışığı kırabilir miyim?" Elbette, o zaman herhangi bir soruna neden olmayabilir, ancak acele saatinde aynı şeyi yapmanız için bir kol sağlayacaktır!


3

Hayır, işletim sisteminin sizin için temizleyeceği sızıntılara sahip olmamalısınız. Nedeni (yukarıdaki cevaplarda kontrol edebildiğim kadarıyla belirtilmemiş), main () öğenizin ne zaman başka bir programda bir işlev / modül olarak yeniden kullanılacağını asla bilmemenizdir . Main () cihazınız başka bir kişinin yazılımında sıkça adlandırılan bir işlev haline gelirse - bu yazılım zaman içinde bellek tüketen bir bellek sızıntısına sahip olacaktır.

aKIV


3

Bellek sızıntısı (yani bellek sızıntılarının sistem performansı üzerindeki etkisini test etmek) amaçlı bir program yazıyorsanız sorun değil.


3

Bir bellek sızıntısının gerçekte ne olduğuna dair birçok yanlış tanım gördüğüme şaşırdım. Somut bir tanım olmadan, bunun kötü bir şey olup olmadığı üzerine bir tartışma olmaz.

Bazı yorumcular haklı olarak işaret ettiği gibi, bir bellek sızıntısı yalnızca bir işlem tarafından ayrılan bellek, işlemin artık referans gösteremeyeceği veya silemeyeceği ölçüde kapsam dışına çıktığında gerçekleşir.

Giderek daha fazla bellek alan bir işlemin sızması gerekmez. Bu belleğe başvurabildiği ve yerini değiştirebildiği sürece, sürecin açık kontrolü altında kalır ve sızdırmaz. İşlem, özellikle belleğin sınırlı olduğu bir sistem bağlamında kötü bir şekilde tasarlanabilir, ancak bu bir sızıntı ile aynı değildir. Tersine, örneğin, 32 baytlık bir tamponun kapsamını kaybetmek, sızan bellek miktarı az olsa bile hala bir sızıntıdır. Bunun önemsiz olduğunu düşünüyorsanız, birisi kütüphane çağrınızın etrafına bir algoritma yazıp 10.000 kez çağırana kadar bekleyin.

Kendi kodunuzda sızıntılara izin vermek için hiçbir neden görmüyorum, ancak küçük. C ve C ++ gibi modern programlama dilleri, programcıların bu tür sızıntıları önlemesine yardımcı olmak için büyük çaba sarf etmektedir ve sızıntıları önlemek için iyi programlama tekniklerini (özellikle belirli dil olanaklarıyla birleştiğinde) benimsememek için nadiren iyi bir argüman vardır.

Kalite veya değişiklik yapma yeteneğinizin kontrolünün son derece sınırlı olabileceği mevcut veya üçüncü taraf kodu ile ilgili olarak, sızıntının ciddiyetine bağlı olarak, azaltmak için işleminizi düzenli olarak yeniden başlatma gibi hafifletici işlemleri kabul etmek veya uygulamak zorunda kalabilirsiniz. sızıntının etkisi.

Mevcut (sızdıran) kodu değiştirmek veya değiştirmek mümkün olmayabilir ve bu nedenle kodu kabul etmek zorunda kalabilirsiniz. Bununla birlikte, bu iyi olduğunu beyan etmekle aynı şey değildir.


2

Kasıtlıysa gerçekten bir sızıntı değil ve önemli bir bellek olmadığı sürece bir sorun değil veya önemli miktarda bellek olarak büyüyebilir. Bir programın ömrü boyunca küresel tahsisleri temizlememek oldukça yaygındır. Sızıntı bir sunucuda veya uzun süren bir uygulamadaysa, zamanla büyür, o zaman bu bir problemdir.


2

Sanırım kendi sorunuzu cevapladınız. En büyük dezavantajı, bellek sızıntısı algılama araçlarına nasıl müdahale ettikleri, ancak bence dezavantajın belirli uygulama türleri için BÜYÜK bir dezavantaj olduğunu düşünüyorum.

Kaya gibi sağlam olması gereken eski sunucu uygulamalarıyla çalışıyorum ancak sızıntıları var ve küreseller bellek algılama araçlarının önüne geçiyor. Bu çok önemli.

Jared Diamond'ın "Çöküşü" kitabında yazar, adadan çıkmak için bir kano yapmak için ihtiyaç duyacağı ağaç olan Paskalya Adası'ndaki son ağacı kestiği adamın ne düşündüğünü merak ediyor. Yıllar önce, ilk global kod tabanımıza eklendiği günü merak ediyorum. Bu yakalanması gereken gündü.


2

Tüm senaryo soruları gibi aynı sorunu görüyorum: Program değiştiğinde ne olur ve aniden on milyon kez küçük bellek sızıntısı deniyor ve programınızın sonu farklı bir yerde, bu yüzden önemli mi? Bir kütüphanedeyse, kütüphane sahipleriyle bir hata günlüğe kaydedin, kendi kodunuza sızıntı koymayın.


Bu durumda bellek sızıntısının etkisi değişir ve sızıntıyı takma önceliğini yeniden değerlendirmeniz gerekir.
John Dibling

@John: En azından sızıntıyı belgelemen iyi olur. O zaman bile, birisinin büyük kırmızı yanıp sönen yorumu görmezden gelmemesine ve yine de kopyalayıp yapıştırma koduna güvenmemesine güvenmem. İlk etapta birisine bunu yapma yeteneğini vermemeyi tercih ederim.
tloach

2

Hayır cevap vereceğim.

Teoride, bir karışıklık bırakırsanız işletim sistemi sizden sonra temizlenir (şimdi bu sadece kaba, ancak bilgisayarların duyguları olmadığı için kabul edilebilir olabilir). Ancak programınız çalıştırıldığında meydana gelebilecek olası her durumu tahmin edemezsiniz. Bu nedenle (bazı davranışların resmi bir kanıtını gerçekleştiremediğiniz sürece), bellek sızıntıları oluşturmak sadece sorumsuz ve profesyonel bir bakış açısından özensizdir.

Üçüncü taraf bir bileşen bellek sızdırıyorsa, bu, yalnızca olası etki nedeniyle değil, aynı zamanda programcıların özensiz çalıştığını ve bunun diğer metrikleri de etkileyebileceğini gösterdiğinden, onu kullanmaya karşı çok güçlü bir tartışmadır. Şimdi, eski sistemleri göz önüne alırsak bu zordur (web tarama bileşenlerini düşünün: bildiklerime göre, bunlar tüm sızıntı bellek) ancak norm olmalıdır.


2

Tarihsel olarak, bazı uç sistemlerde bazı işletim sistemlerinde önemliydi. Bu uç durumlar gelecekte var olabilir.

İşte bir örnek, Sun 3 çağındaki SunOS'ta, bir işlem exec (veya daha geleneksel olarak çatal ve sonra exec) kullandıysa, sonraki yeni işlem ebeveynle aynı bellek ayak izini devralır ve küçülemezdi . Bir üst süreç 1/2 gig bellek ayırdıysa ve exec çağırmadan önce boşlamadıysa, alt süreç aynı 1/2 gig'i kullanmaya başlamıştı (ayrılmış olmasa bile). Bu davranış en iyi, bir bellek domuzu olan SunTools (varsayılan pencere sistemleri) tarafından sergilendi. Ortaya çıkan her uygulama çatal / exec ile oluşturuldu ve SunTools ayak izini devraldı, hızlı bir şekilde takas alanını doldurdu.


2

Bu zaten nauseam tartışıldı . Alt satırda bir bellek sızıntısı bir hata ve düzeltilmesi gerektiğidir. Üçüncü taraf bir kütüphane hafızayı sızdırıyorsa, başka neyin yanlış olduğunu merak ediyor, değil mi? Bir araba inşa ediyorsanız, ara sıra yağ sızdıran bir motor kullanır mıydınız? Sonuçta, başka biri motoru yaptı, bu yüzden senin hatan değil ve tamir edemezsin, değil mi?


Ancak ara sıra yağ sızdıran bir motora sahip bir arabanız varsa, onu düzeltmek için para harcıyor musunuz yoksa yağ seviyelerine dikkat ediyor musunuz ve zaman zaman dolduruyorsunuz. Cevap her türlü faktöre bağlıdır.
ince

Bu araba sahibi olmakla ilgili değil. Bu bir araba yapmakla ilgili. Bellek sızıntısı olan üçüncü taraf bir kütüphane alırsanız ve kesinlikle kullanmanız gerekiyorsa, onunla yaşarsınız. Ancak sistem veya kütüphane yazan kişi sizseniz, hatasız olduğundan emin olmak sizin sorumluluğunuzdadır.
Dima

+1, diğer hatalar gibi davranın. (Bu, kitabımda "anında düzelt" anlamına gelmiyor, ancak "kesin olarak düzeltilmesi gerekiyor")
peterchen

2

Genellikle tek başına bir uygulamada bellek sızıntısı, programdan çıkıldığında temizlendiği için ölümcül değildir.

Çıkacak şekilde tasarlanan Sunucu programları için ne yaparsınız?

Kaynakların doğru bir şekilde tahsis edildiği ve serbest bırakıldığı bir kod tasarlama ve uygulamayan bir programcıysanız, o zaman sizinle veya kodunuzla ilgili bir şey istemiyorum. Sızan hafızanızı temizlemek istemezseniz, kilitleriniz ne olacak? Onları da orada takılıyor musun? Çeşitli dizinlerde geçici dosyaların küçük bir kısmını bırakıyor musunuz?

O hafızayı sızdırıp programın temizlenmesine izin verilsin mi? Kesinlikle değil. Hatalara, böceklere ve daha fazla hataya yol açan kötü bir alışkanlıktır.

Kendinizi temizleyin. Annen burada daha fazla çalışmaz.


Bellek sızıntıları ve segmentasyon hataları sınırlı hasara neden olacak şekilde, iş parçacıkları yerine kasıtlı olarak işlemleri kullanan sunucu programlarında çalıştım.
ince

İlginç bir yaklaşım. Çıkış yapamayan ve hafızayı yitirmeye devam eden süreçler hakkında biraz endişeliyim.
EvilTeach

2

Genel bir kural olarak, kaçınamayacağınızı düşündüğünüz hafıza sızıntılarınız varsa, nesne sahipliği hakkında daha fazla düşünmeniz gerekir.

Ama sorunuza, kısaca cevabım üretim kodunda, evet. Geliştirme sırasında hayır . Bu geriye doğru görünebilir, ama işte mantığım:

Tarif ettiğiniz durumda, programın sonuna kadar hafızanın nerede tutulduğu, onu serbest bırakmamak mükemmel olur. İşleminiz sona erdiğinde, işletim sistemi yine de temizlenecektir. Aslında, kullanıcının deneyimini daha iyi hale getirebilir: Üzerinde çalıştığım bir oyunda, programcılar çıkmadan önce tüm belleği boşaltmanın daha temiz olacağını düşündüler ve programın kapatılması yarım dakika kadar sürdü! Bunun yerine exit () adı verilen hızlı bir değişiklik, işlemin hemen kaybolmasını sağladı ve kullanıcıyı istediği masaüstüne geri koydu.

Bununla birlikte, hata ayıklama araçları konusunda haklısınız: Bir fit atacaklar ve tüm yanlış pozitifler gerçek hafızanızı bulmanın bir acıya neden olabilir. Bu nedenle, her zaman belleği serbest bırakan hata ayıklama kodunu yazın ve gönderirken devre dışı bırakın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.