Amalan terbaik untuk memudahkan pengumpulan sampah di .Net

Di Microsoft.Net, pengumpulan sampah adalah mekanisme yang digunakan oleh Common Language Runtime (CLR) untuk membersihkan sumber yang digunakan oleh aplikasi anda. Apabila anda membuat objek di. Net, objek tersebut disimpan di timbunan terurus. Walaupun anda perlu membuat objek, dalam kebanyakan kes, anda tidak perlu risau untuk membersihkan objek - waktu proses akan melakukannya untuk anda.

Walau bagaimanapun, anda harus menggunakan amalan terbaik dalam aplikasi anda untuk memudahkan pengumpulan sampah dan membantunya membersihkan sumber dengan lebih cepat. Walaupun .Net mahir menuntut semula objek yang diuruskan, anda harus mengikuti panduan tertentu untuk memudahkan pengumpulan sampah dengan lebih cepat untuk meningkatkan prestasi aplikasi anda. Dalam artikel ini saya ingin menyampaikan perbincangan mengenai bagaimana pengumpulan sampah berfungsi dan amalan terbaik yang terlibat untuk memudahkan pengumpulan sampah di .Net.

Bilakah pengumpulan sampah dilakukan?

Pengumpulan sampah dilakukan ketika sistem kekurangan memori fizikal yang tersedia atau GC.Collect()kaedah disebut secara jelas dalam kod aplikasi anda. Objek yang tidak lagi digunakan atau tidak dapat dijangkau dari akar umbi adalah calon pengumpulan sampah. Pada hakikatnya, pengumpul sampah membersihkan memori yang ditempati oleh objek yang tidak mempunyai rujukan.

Generasi

Masa berjalan mengatur timbunan terurus menjadi generasi. Ia menggunakan generasi ini untuk mengatur objek jangka pendek dan jangka panjang. Harus diingat bahawa pengumpul sampah bekerja lebih kerap pada generasi yang lebih rendah daripada yang lebih tinggi. Generasi 0 mengandungi objek jangka pendek seperti objek sementara. Apabila objek dibuat, ia disimpan dalam Generasi 0 melainkan objek itu besar. Sekiranya objek itu adalah objek besar, ia disimpan di Heap Objek Besar (LOH) pada Generasi 2. Dalam kebanyakan kes, objek Generasi 0 diambil semula oleh pengumpul sampah ketika ia berjalan di latar belakang.

Semasa menulis kod, anda harus mematuhi amalan terbaik tertentu. Sebagai contoh, anda harus membuat objek dalam ruang lingkup tempatan sebanyak mungkin untuk memudahkan pengumpulan sampah. Objek yang dibuat dalam ruang lingkup yang lebih tinggi biasanya berada di memori untuk jangka masa yang lebih lama. Anda boleh memanfaatkan profiler CLR untuk memahami corak peruntukan aplikasi anda.

Anda harus mengelakkan memanggil GC.Collect()kaedah kerana ia menyebabkan koleksi semua generasi (Generasi 0, 1, dan 2). Apabila anda membuat panggilan ke GC.Collect()kaedah tersebut, masa berjalan akan mengunjungi semua objek langsung dalam aplikasi anda. Ini memerlukan banyak masa dan, oleh itu, merupakan operasi yang sangat mahal. Akibatnya, bukan kaedah yang baik untuk memanggil GC.Collect()kaedah tersebut.

Sekiranya anda harus memanggil GC.Collect()kaedah, anda harus memanggil GC.WaitForPendingFinalizers()selepas panggilan GC.Collect()untuk memastikan bahawa benang pelaksana saat ini menunggu hingga penyelesaikan untuk semua objek telah dilaksanakan.

Seterusnya, anda harus membuat panggilan ke GC.Collect()kaedah sekali lagi untuk memastikan bahawa anda mengumpulkan objek mati yang masih ada. Objek-objek mati ini mungkin telah dibuat kerana panggilan ke kaedah finalis pada objek. Coretan kod berikut menunjukkan bagaimana kaedah ini digunakan.

System.GC.Collect();

System.GC.WaitForPendingFinalizers();

System.GC.Collect();

Anda harus memastikan bahawa anda meminimumkan peruntukan tersembunyi dan menulis kod anda sedemikian rupa sehingga kemungkinan promosi objek jangka pendek ke generasi yang lebih tinggi dihapuskan. Anda tidak harus merujuk objek yang berumur pendek dari yang lama untuk mengelakkan promosi objek yang berumur pendek ke generasi yang lebih tinggi.

Anda juga harus mengelakkan menulis finalis untuk kelas anda. Sekiranya anda mempunyai penentu yang dilaksanakan di kelas anda, objek dari kelas tersebut akan menjadi objek yang lama kerana masa perlaksanaan perlu mempromosikan objek yang dapat diselesaikan kepada generasi yang lebih tua. Anda harus menetapkan objek menjadi nol sebelum membuat panggilan lama jika objek seperti itu tidak diperlukan oleh aplikasi. Sekiranya anda tidak lagi memerlukan objek statik atau objek lain dalam aplikasi anda, anda harus menetapkannya sebagai nol sebelum membuat panggilan yang lama dijalankan. Anda tidak boleh menetapkan pemboleh ubah tempatan menjadi nol kerana tidak diperlukan; runtime dapat menentukan objek tempatan mana yang tidak dirujuk dalam kod anda atau tidak digunakan lebih jauh, jadi anda tidak perlu menetapkan pemboleh ubah tempatan untuk membatalkan secara jelas.