Apakah Go terkena kebocoran memori halus yang sama dengan Java?

91

Berikut fakta-faktanya:

  • bahasa Go memiliki pengumpul sampah.

  • Java memiliki tempat pengumpulan sampah

  • banyak program Java yang mengalami kebocoran memori (halus atau tidak)

Sebagai contoh program Java yang mengalami kebocoran memori (bukan untuk yang lemah hati, pertanyaannya mungkin menggoyahkan keyakinan Anda), lihat di sini tentang program Java kecil bernama Tomcat yang bahkan memiliki tombol "temukan kebocoran": Adakah cara untuk menghindari kebocoran memori undeployment di Tomcat?

Jadi saya bertanya-tanya: akankah program yang ditulis dalam Go menunjukkan jenis kebocoran memori (halus atau tidak) yang sama dengan beberapa program yang ditulis di pameran Java?

SintaksT3rr0r
sumber
29
"Banyak program Java memiliki (halus atau tidak) kebocoran memori" apakah Anda memiliki bukti tentang "fakta" ini atau itu hanya pokok pembicaraan.
Peter Lawrey
17
@ Webinator: Saya rasa Anda perlu memberikan contoh dari salah satu "kebocoran memori halus" yang "banyak" dimiliki oleh program Java. Kecuali jika Anda mengklaim bug di pengumpul sampah, satu-satunya cara untuk membocorkan memori di Java murni adalah dengan menyimpan referensi yang tidak lagi Anda gunakan, misalnya dengan meletakkan objek dalam koleksi dan tidak pernah menghapusnya dari koleksi itu. Jika ini jenis kebocoran yang Anda maksud, maka tidak ada bahasa di dunia ini yang akan melindungi mereka, termasuk Go.
JeremyP
14
Berikut adalah kebocoran memori yang saya bicarakan (+200 suara positif, jawaban dengan +150 suara positif, banyak kebocoran memori Java yang sebenarnya dijelaskan): stackoverflow.com/questions/6470651/…
SyntaxT3rr0r
6
Tentu saja program JAVA memang mengalami kebocoran memori, lupakan saja untuk mengatur beberapa referensi ke null ketika Anda membutuhkannya lagi. Sering terjadi dalam koleksi persisten yang besar (seperti cache), dengan pola desain pengamat atau variabel lokal utas. Ini tidak teoretis, saya memperbaiki sendiri beberapa kebocoran memori dalam produksi. Dan ini bukan anti Java. Saya adalah pengembang JAWA penuh waktu selama lebih dari 5 tahun, telah mengerjakan banyak proyek berbeda. Tidak menyadari bahwa Anda dapat mengalami kebocoran memori di JAVA (atau semua bahasa lain yang ada) bukanlah fanboyisme, lebih banyak kurangnya pemahaman tentang bagaimana hal-hal sebenarnya bekerja.
Nicolas Bousquet
6
Pertanyaan ini bisa dilakukan tanpa drama dan komentar tentang "fanboyisme", "mengguncang keyakinan seseorang" dan sejenisnya. Esp. karena seluruh diskusi bermuara pada "definisi saya memory leaklebih baik daripada definisi Anda".
LAFK mengatakan Reinstate Monica

Jawaban:

44

Anda membingungkan berbagai jenis kebocoran memori di sini.

Kebocoran memori berbasis manajemen memori eksplisit yang keji hilang di Java (atau bahasa berbasis GC lainnya). Kebocoran ini disebabkan oleh kehilangan akses sepenuhnya ke potongan memori tanpa menandainya sebagai tidak digunakan.

"Kebocoran memori" masih ada di Jawa dan setiap bahasa lain di muka planet ini sampai komputer dapat membaca pikiran kita masih bersama kita, dan akan terus ada di masa mendatang. Kebocoran ini disebabkan oleh kode / pemrogram menyimpan referensi ke objek yang secara teknis tidak lagi diperlukan. Ini pada dasarnya adalah bug logika, dan tidak dapat dicegah dalam bahasa apa pun menggunakan teknologi saat ini.

james
sumber
23
Kebocoran memori hanya terjadi ketika Anda lupa mengosongkan memori. Di Java, hal ini terjadi saat Anda lupa menyetel referensi ke null. Di C ++ itu terjadi jika Anda lupa menelepon gratis. Keduanya adalah kasus kebocoran memori yang valid. Dan masalah fundamentalnya sama, Anda program mengkonsumsi lebih banyak memori sampai akhirnya crash dengan kesalahan OutOfMemory.
Nicolas Bousquet
1
Meskipun benar bahwa tidak ada bahasa yang dapat mencegah pemrogram membuat kesalahan logika seperti itu, juga benar bahwa beberapa kesalahan tersebut ada di Java SDK itu sendiri (lihat, misalnya, java.util.logging.Levelyang berisi statis pribadi ArrayListtempat semua objek yang ditempatkan pada konstruksi, dan dari mana mereka tidak pernah dihapus), yang membuatnya lebih sulit untuk menghindarinya saat memprogram Java daripada dalam beberapa bahasa lain yang tidak mengandung kekurangan seperti itu
Jules
7
Saya pikir OP bertanya tentang kebocoran memori objek yang benar-benar tidak dapat dijangkau seperti dalam jawaban yang diterima dari pertanyaan terkait. Kebocoran memori yang disebabkan oleh pemuatan kelas dari utas. -1
qbt937
1
Dapat juga dibayangkan bahwa analisis statis dapat menentukan apakah referensi terus ada setelah masa manfaatnya yang berguna - tidak perlu membaca pikiran.
Kyle Strand
1
@Amrit Tidak, pengumpul sampah mengumpulkan memori yang tidak lagi Anda rujuk. Tidak ada cara untuk mengetahui apakah OK untuk menghapus sesuatu yang masih Anda rujuk.
Raphael Schmitz
19

Sangat mungkin program Go akan menunjukkan kebocoran memori. Implementasi Go saat ini memiliki pengumpul sampah mark-and-sweep sederhana. Ini hanya dimaksudkan sebagai solusi sementara dan tidak dimaksudkan sebagai pengumpul sampah jangka panjang. Lihat halaman ini untuk info lebih lanjut. Lihat di bawah tajuk Go Garbage Collector. Halaman itu bahkan memiliki link ke kode untuk versi saat ini jika Anda menginginkannya.

Poindexter
sumber
1
Salah satu masalah mark and sweep collector di Java adalah fragementasi memori. Meskipun secara teknis bukan memori, itu bisa menjadi hilangnya memori yang tersedia untuk aplikasi.
Peter Lawrey
9

'Kebocoran memori' adalah ketika bagian dari memori yang menurut pemrogram akan dibebaskan tidak dibebaskan. Ini bisa terjadi dalam bahasa apa pun, sampah dikumpulkan atau tidak. Penyebab umum dalam bahasa GC adalah mempertahankan referensi tambahan ke memori.

"Bahasa tidak menyebabkan kebocoran memori, pemrogram menyebabkan kebocoran memori".

DJClayworth
sumber
8

Pengumpulan sampah atau tidak, Anda dapat menulis program yang memiliki kebocoran memori di Java, Go, atau bahasa lain untuk sebagian besar.

Pengumpulan Sampah memang mengambil sebagian beban dari pemrogram tetapi tidak mencegah kebocoran sepenuhnya.

jzd
sumber
4
Saya tahu saya tahu. Saya berbicara secara khusus tentang kebocoran memori yang agak halus yang ada di Java bahkan Java yang sulit, pada awalnya, dipasarkan sebagai bahasa di mana kebocoran memori tidak ada berkat GC .
SyntaxT3rr0r
4
Maaf itu tidak jelas. Anda mengatakan "banyak program Java (halus atau tidak) kebocoran memori".
jzd
3

Anda mencampurkan tingkat abstraksi di sini: kebocoran memori disebabkan oleh bug di perpustakaan (di mana objek saling mereferensikan melalui rantai 'a memegang referensi ke b' serta trade-off dalam implementasi pengumpul sampah antara efisiensi dan akurasi. Berapa banyak waktu yang ingin Anda habiskan untuk mencari loop seperti itu? Jika menghabiskan dua kali lebih banyak, Anda akan dapat mendeteksi loop dua kali lebih lama.

Jadi masalah kebocoran memori bukanlah bahasa pemrograman khusus, tidak ada alasan bahwa GO dengan sendirinya harus lebih baik atau lebih buruk daripada Java.

florin
sumber
1
Saya tidak sepenuhnya setuju. Kebocoran memori disebabkan oleh fakta bahwa Java memungkinkan untuk mengambil gambar sendiri dan tidak selalu terkait dengan bug perpustakaan. Banyak programmer menulis program yang perlahan tapi pasti membocorkan memori di Java dan itu adalah kesalahan mereka sendiri, bukan kesalahan perpustakaan. Selain itu, jika Java GC membuat pengorbanan waktu / kemungkinan kebocoran, apakah Go membuat pengorbanan yang sama?
SyntaxT3rr0r
1
dan pertanyaannya sebenarnya bukan "berapa banyak waktu yang ingin saya habiskan untuk menemukan putaran seperti itu?" Pertanyaannya adalah "Berapa banyak waktu yang ditentukan oleh spesifikasi yang dihabiskan Go GC pada loop seperti itu" , yang IMHO merupakan pertanyaan yang menarik.
SyntaxT3rr0r
16
Rantai referensi siklik tidak mencegah pengumpulan sampah di Java.
Andy Thomas