Saya menulis C ++ selama 10 tahun. Saya mengalami masalah memori, tetapi bisa diperbaiki dengan upaya yang wajar.
Selama beberapa tahun terakhir saya telah menulis C #. Saya menemukan masih banyak masalah memori. Mereka sulit untuk didiagnosis dan diperbaiki karena tidak adanya determinasi, dan karena filosofi C # adalah bahwa Anda tidak perlu khawatir tentang hal-hal seperti itu ketika Anda benar-benar melakukannya.
Satu masalah khusus yang saya temukan adalah bahwa saya harus membuang dan membersihkan segala sesuatu dalam kode secara eksplisit. Jika saya tidak melakukannya, maka profiler memori tidak benar-benar membantu karena ada begitu banyak sekam melayang tentang Anda tidak dapat menemukan kebocoran di dalam semua data yang mereka coba tunjukkan kepada Anda. Saya ingin tahu apakah saya mendapat ide yang salah, atau apakah alat yang saya miliki bukan yang terbaik.
Strategi dan alat apa yang berguna untuk mengatasi kebocoran memori di .NET?
sumber
Jawaban:
Saya menggunakan MemProfiler Scitech ketika saya mencurigai ada kebocoran memori.
Sejauh ini, saya merasa sangat andal dan kuat. Ini telah menghemat daging saya setidaknya pada satu kesempatan.
GC berfungsi dengan sangat baik dalam .NET IMO, tetapi sama seperti bahasa atau platform lainnya, jika Anda menulis kode yang buruk, hal-hal buruk terjadi.
sumber
Hanya untuk masalah pelepasan-untuk-buang, coba solusi yang dijelaskan dalam posting blog ini . Inilah intinya:
sumber
Kami telah menggunakan Ants Profiler Pro oleh perangkat lunak Red Gate di proyek kami. Ini bekerja sangat baik untuk semua aplikasi berbasis bahasa .NET.
Kami menemukan bahwa .NET Garbage Collector sangat "aman" dalam membersihkan objek dalam memori (sebagaimana mestinya). Itu akan menjaga benda-benda di sekitar hanya karena kita mungkin menggunakannya di masa depan. Ini berarti kami harus lebih berhati-hati dengan jumlah objek yang kami gembungkan dalam memori. Pada akhirnya, kami mengubah semua objek data kami menjadi "mengembang saat diminta" (tepat sebelum bidang diminta) untuk mengurangi overhead memori dan meningkatkan kinerja.
EDIT: Berikut adalah penjelasan lebih lanjut tentang apa yang saya maksud dengan "mengembang pada permintaan." Dalam model objek kami dari basis data kami, kami menggunakan properti dari objek induk untuk mengekspos objek anak. Sebagai contoh jika kita memiliki beberapa catatan yang mereferensikan catatan "detail" atau "pencarian" lainnya pada basis satu-ke-satu, kita akan menyusunnya seperti ini:
Kami menemukan bahwa sistem di atas menciptakan beberapa masalah memori dan kinerja nyata ketika ada banyak catatan dalam memori. Jadi kami beralih ke sistem di mana objek digembungkan hanya ketika diminta, dan panggilan basis data dilakukan hanya jika diperlukan:
Ini ternyata jauh lebih efisien karena benda-benda disimpan keluar dari memori sampai mereka diperlukan (metode Dapatkan diakses). Ini memberikan peningkatan kinerja yang sangat besar dalam membatasi hit basis data dan keuntungan besar pada ruang memori.
sumber
Anda masih perlu khawatir tentang memori ketika Anda menulis kode terkelola kecuali aplikasi Anda sepele. Saya akan menyarankan dua hal: pertama, baca CLR via C # karena itu akan membantu Anda memahami manajemen memori dalam .NET. Kedua, belajar menggunakan alat seperti CLRProfiler (Microsoft). Ini dapat memberi Anda gambaran tentang apa yang menyebabkan kebocoran memori Anda (misalnya, Anda dapat melihat fragmentasi tumpukan objek besar Anda)
sumber
Apakah Anda menggunakan kode yang tidak dikelola? Jika Anda tidak menggunakan kode yang tidak dikelola, menurut Microsoft, kebocoran memori dalam pengertian tradisional tidak dimungkinkan.
Memori yang digunakan oleh suatu aplikasi mungkin tidak dirilis, jadi alokasi memori aplikasi dapat tumbuh sepanjang umur aplikasi.
Untuk menangani masalah jenis ini, Anda dapat menerapkan IDisposable . Jika Anda ingin melihat beberapa strategi untuk menangani manajemen memori, saya sarankan mencari IDisposable, XNA, manajemen memori karena pengembang game harus memiliki pengumpulan sampah yang lebih dapat diprediksi dan karenanya harus memaksa GC untuk melakukan hal tersebut.
Satu kesalahan umum adalah tidak menghapus event handler yang berlangganan suatu objek. Berlangganan event handler akan mencegah objek didaur ulang. Juga, lihat pernyataan menggunakan yang memungkinkan Anda untuk membuat ruang lingkup terbatas untuk seumur hidup sumber daya.
sumber
Blog ini memiliki beberapa langkah mudah menggunakan windbg dan alat lain untuk melacak kebocoran memori dari semua jenis. Bacaan yang bagus untuk mengembangkan keterampilan Anda.
sumber
Saya baru saja mengalami kebocoran memori di layanan windows, yang saya perbaiki.
Pertama, saya mencoba MemProfiler . Saya merasa sangat sulit digunakan dan sama sekali tidak ramah pengguna.
Lalu, saya menggunakan JustTrace yang lebih mudah digunakan dan memberi Anda lebih banyak detail tentang objek yang tidak dibuang dengan benar.
Itu memungkinkan saya untuk memecahkan kebocoran memori dengan sangat mudah.
sumber
Jika kebocoran yang Anda amati adalah karena implementasi cache yang tidak terkendali, ini adalah skenario di mana Anda mungkin ingin mempertimbangkan penggunaan WeakReference. Ini bisa membantu memastikan bahwa memori dilepaskan ketika diperlukan.
Namun, IMHO akan lebih baik untuk mempertimbangkan solusi yang dipesan lebih dahulu - hanya Anda yang benar-benar tahu berapa lama Anda perlu menyimpan benda-benda di sekitarnya, jadi merancang kode tata graha yang sesuai untuk situasi Anda biasanya merupakan pendekatan terbaik.
sumber
Saya lebih suka dotmemory dari Jetbrains
sumber
Pistol besar - Alat Debugging untuk Windows
Ini adalah koleksi alat yang luar biasa. Anda dapat menganalisis tumpukan yang dikelola dan yang tidak dikelola dengan itu dan Anda dapat melakukannya secara offline. Ini sangat berguna untuk men-debug salah satu aplikasi ASP.NET kami yang terus melakukan daur ulang karena terlalu banyak menggunakan memori. Saya hanya harus membuat dump memori penuh dari proses hidup yang berjalan di server produksi, semua analisis dilakukan secara offline di WinDbg. (Ternyata beberapa pengembang terlalu sering menggunakan penyimpanan Sesi dalam memori.)
"Jika rusak itu ..." blog memiliki artikel yang sangat berguna tentang masalah ini.
sumber
Hal terbaik untuk diingat adalah untuk melacak referensi ke objek Anda. Sangat mudah untuk berakhir dengan menggantung referensi ke objek yang tidak Anda pedulikan lagi. Jika Anda tidak akan menggunakan sesuatu lagi, singkirkan itu.
Biasakan menggunakan penyedia cache dengan geser masa kadaluwarsa, sehingga jika sesuatu tidak direferensikan untuk jendela waktu yang diinginkan itu dereferenced dan dibersihkan. Tetapi jika sedang diakses banyak itu akan mengatakan dalam memori.
sumber
Salah satu alat terbaik adalah menggunakan Alat Debugging untuk Windows , dan mengambil dump memori dari proses menggunakan adplus , kemudian menggunakan windbg dan plugin sos untuk menganalisis memori proses, utas, dan tumpukan panggilan.
Anda dapat menggunakan metode ini untuk mengidentifikasi masalah di server juga, setelah menginstal alat, berbagi direktori, lalu menyambung ke berbagi dari server menggunakan (penggunaan net) dan mengambil crash atau hang dump proses.
Kemudian analisa secara offline.
sumber
Setelah salah satu perbaikan saya untuk aplikasi terkelola, saya memiliki hal yang sama, seperti cara memverifikasi bahwa aplikasi saya tidak akan memiliki kebocoran memori yang sama setelah perubahan saya berikutnya, jadi saya telah menulis sesuatu seperti kerangka Verifikasi Rilis Objek, silakan lihat paket NuGet ObjectReleaseVerification . Anda dapat menemukan sampel di sini https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample , dan informasi tentang sampel ini http://outcoldman.ru/en/blog/show/322
sumber
Dari Visual Studio 2015 pertimbangkan untuk menggunakan di luar kotak alat diagnostik Penggunaan Memori untuk mengumpulkan dan menganalisis data penggunaan memori.
Alat Penggunaan Memori memungkinkan Anda mengambil satu atau lebih snapshot dari tumpukan memori yang dikelola dan asli untuk membantu memahami dampak penggunaan memori dari jenis objek.
sumber
salah satu alat terbaik yang saya gunakan DotMemory. Anda dapat menggunakan alat ini sebagai ekstensi dalam VS.setelah menjalankan aplikasi Anda, Anda dapat menganalisis setiap bagian dari memori (berdasarkan Object, NameSpace, dll) yang digunakan aplikasi Anda dan mengambil snapshot dari itu , Bandingkan dengan SnapShots lainnya. DotMemory
sumber