Go, Java ile aynı ince bellek sızıntılarına mı maruz kalıyor?


91

İşte gerçekler:

  • Go dili çöp toplayıcısına sahiptir.

  • Java'nın bir çöp koleksiyonu var

  • birçok Java programında (ince veya ince) bellek sızıntıları var

Bellek sızıntıları olan bir Java programı örneği olarak (gönül rahatlığı için değil, bu soru inançlarınızı sarsabilir), "sızıntıları bul" düğmesi bile olan Tomcat adlı küçük bir Java programı hakkında buraya bakın: Bir yolu var mı Tomcat'te konuşlandırılmamış bellek sızıntılarını önlemek için?

Bu yüzden merak ediyorum: Go'da yazılan programlar, Java'da yazılmış bazı programların sergilediği aynı tür (ince veya gizli) bellek sızıntılarını sergileyecek mi?


29
"Java programlarının çoğunda bellek sızıntıları var (ince olsun ya da olmasın)" bu "gerçek" hakkında herhangi bir kanıtınız var mı yoksa bu sadece bir konuşma noktası mı?
Peter Lawrey

17
@Webinator: Bence Java programlarının sahip olduğu bu "ince bellek sızıntılarından" birine bir örnek vermen gerekiyor. Çöp toplayıcısında bir hata olduğunu iddia etmediğiniz sürece, saf Java'da bellek sızdırmanın tek yolu, artık kullanmadığınız referanslara, örneğin nesneleri bir koleksiyona koyarak ve onları o koleksiyondan asla kaldırmayarak devam etmektir. Bahsettiğiniz türden sızıntı buysa, Go dahil dünyadaki hiçbir dil bunlara karşı koruma sağlamaz.
JeremyP

14
İşte bahsettiğim bellek sızıntıları (+200 olumlu oy, +150 olumlu oy içeren yanıtlar, çok sayıda gerçek Java bellek sızıntısı açıklandı): stackoverflow.com/questions/6470651/…
SyntaxT3rr0r

6
Elbette, JAVA programlarında bellek sızıntıları var, sadece daha uzun süre ihtiyaç duyduğunuzda null'a referans vermeyi unutun. Gözlemci tasarım deseni veya iş parçacığı yerel değişkenleri ile büyük kalıcı koleksiyonlarda (önbellekler gibi) sık sık görülür. Bu teorik değil, üretimde birkaç bellek sızıntısını kendim düzelttim. Ve bu Java karşıtı değil. 5 yıldan daha uzun süredir tam zamanlı bir JAVA geliştiriciyim, birçok farklı proje üzerinde çalışıyorum. JAVA'da (veya diğer tüm mevcut dilde) bellek sızıntısı yaşayabileceğinizi bilmemek fanboyizm değil, işlerin gerçekte nasıl çalıştığını anlamamaktır.
Nicolas Bousquet

6
Bu soru, "fanboyizm", "birinin inançlarını sarsmak" ve benzerleri hakkında drama ve yorumlar olmadan da yapılabilir. Esp. çünkü tüm tartışma "benim tanımım memory leaksizinkinden daha iyi" şeklinde özetleniyor.
LAFK,

Yanıtlar:


44

Burada farklı bellek sızıntı türlerini karıştırıyorsunuz.

Kötü, açık bellek yönetimi tabanlı bellek sızıntıları Java'da (veya herhangi bir GC tabanlı dilde) ortadan kalktı. Bu sızıntılara, kullanılmamış olarak işaretlenmeden bellek parçalarına erişimin tamamen kaybedilmesi neden olur.

Java'da ve gezegenin yüzündeki diğer tüm dillerde hala mevcut olan "bellek sızıntıları", bilgisayar zihnimizi okuyana kadar hala bizimle ve öngörülebilir gelecekte olacak. Bu sızıntılara, teknik olarak artık ihtiyaç duyulmayan nesnelere referans tutan kod / programcı neden olur. Bunlar temelde mantıksal hatalardır ve mevcut teknolojileri kullanan herhangi bir dilde engellenemezler.


23
Hafıza sızıntısı, hafızayı boşaltmayı unuttuğunuz zamandır. Java'da bu, referansları null olarak ayarlamayı unuttuğunuzda gerçekleşir. C ++ 'da ücretsiz aramayı unutursanız olur. Her ikisi de geçerli bellek sızıntısı durumlarıdır. Ve temel sorun aynıdır, programınız bir OutOfMemory hatasıyla sonunda çökene kadar daha fazla bellek tüketir.
Nicolas Bousquet

1
Hiçbir dilin programcının bu tür mantık hatalarını yapmasını engelleyemeyeceği doğru olsa da, Java SDK'sının kendisinde de bu tür hataların var olduğu da doğrudur (örneğin, içine inşa edilen bu tür tüm nesnelerin bulunduğu java.util.logging.Levelözel bir statik içeren ArrayListinşa üzerine yerleştirilir ve asla kaldırılmaz), bu da Java'yı programlarken bunlardan kaçınmayı, bu tür kusurlar içermeyen başka bir dilde olduğundan daha zor hale getirir
Jules

7
Bence OP, bağlantılı sorunun kabul edilen cevabında olduğu gibi gerçekten ulaşılamayan nesnelerin bellek sızıntılarını soruyordu. İş parçacıklarından sınıf yüklemesinin neden olduğu bellek sızıntısı. -1
qbt937

1
Statik analizin, referansların faydalı ömürleri boyunca var olmaya devam edip etmediğini belirleyebileceği de düşünülebilir - zihin okuma gerekmez.
Kyle Strand

1
@Amrit Hayır, çöp toplayıcı artık referansınız olmayan belleği toplar . Hala referans aldığınız bir şeyi kaldırmanın uygun olup olmadığını bilmenin hiçbir yolu yoktur.
Raphael Schmitz

19

Go programlarının bellek sızıntıları göstermesi çok olasıdır. Mevcut Go uygulaması basit bir işaret ve süpür çöp toplayıcısına sahiptir. Bu yalnızca geçici bir çözüm olarak tasarlanmıştır ve uzun vadeli çöp toplayıcı olarak tasarlanmamıştır. Daha fazla bilgi için bu sayfaya bakın . Başlığın altına bakın Go Garbage Collector. Eğer bu kadar eğilimliyseniz, o sayfada mevcut sürüm için bir kod bağlantısı bile vardır.


1
Java'daki mark ve süpürme toplayıcısının sorunlarından biri bellek parçalanmasıdır. Teknik olarak bir bellek olmasa da, uygulamanın kullanabileceği bellek kaybı olabilir.
Peter Lawrey

9

Bir 'bellek sızıntısı', programcının serbest bırakılacağını düşündüğü bir bellek parçasının serbest kalmamasıdır. Bu, herhangi bir dilde olabilir, çöp toplanır veya toplanmaz. GC dillerindeki olağan neden, belleğe ek bir referansı korumaktır.

"Diller bellek sızıntılarına neden olmaz, programcılar bellek sızıntılarına neden olur".


8

Çöp toplama veya toplama, Java, Go veya başka herhangi bir dilde bellek sızıntısı olan bir program yazabilirsiniz.

Çöp Toplama, programcının yükünün bir kısmını alır, ancak sızıntıları tamamen engellemez.


4
Biliyorum biliyorum. Özellikle Java'da var olan bir tür ince bellek sızıntılarından bahsediyorum, zorlu Java bile başlangıçta GC sayesinde bellek sızıntılarının olmadığı bir dil olarak pazarlanıyordu .
SözdizimiT3rr0r

4
Üzgünüm bu net değildi. "Birçok Java programında (ince veya ince) bellek sızıntıları var" dediniz.
jzd

3

Burada soyutlama düzeylerini karıştırıyorsunuz: bellek sızıntıları kitaplıktaki hatalardan kaynaklanmaktadır (burada nesneler, 'a, b'ye atıfta bulunuyor' zincirleri olsa da, çöp toplayıcının uygulanmasında verimlilik ve Doğruluk. Bu tür döngüleri bulmak için ne kadar zaman harcamak istiyorsunuz? İki kat daha fazla harcarsanız, döngüleri iki kat daha uzun süre tespit edebilirsiniz.

Dolayısıyla, bellek sızıntısı sorunu programlama diline özgü değildir, GO'nun Java'dan daha iyi veya daha kötü olması için hiçbir neden yoktur.


1
Ben tamamen aynı fikirde değilim. Bellek sızıntıları, Java'nın tek kişiyi ayağa çekmeyi mümkün kıldığı gerçeğinden kaynaklanmaktadır ve bunun mutlaka kitaplık hatasıyla ilgili olması gerekmez. Pek çok programcı Java'da yavaş ama kesin olarak bellek sızdıran programlar yazıyor ve bu kendi hatası, kütüphanelerin hatası değil. Ayrıca, Java GC tam olarak bir zaman / olası sızıntı ödünleşimi yapıyorsa, Go aynı ödünleşmeleri mi yapıyor?
SözdizimiT3rr0r

1
ve soru gerçekten "bu tür döngüleri bulmak için ne kadar zaman harcamak istiyorum?" değil. Soru, "Spesifikasyonlar Go GC'nin bu tür döngüler için ne kadar zaman harcadığını zorunlu kılıyor" , ki IMHO ilginç bir sorudur.
SyntaxT3rr0r

16
Döngüsel referans zincirleri, Java'da çöp toplamayı engellemez.
Andy Thomas
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.