Dua sen saya pada metode GC.Collect di C #

Metode GC.Collect () telah lama populer di kalangan pengembang .Net. Namun, hampir tidak sedikit dari kita yang tahu bagaimana cara kerjanya atau, jika diperlukan panggilan ke sana.

CLR (Common Language Runtime) mengadopsi pengumpulan sampah sebagai mekanisme untuk membersihkan sumber daya yang dikonsumsi oleh aplikasi Anda. Perhatikan bahwa saat Anda membuat objek dalam .Net, objek tersebut disimpan di heap terkelola, dan setelah selesai menggunakannya, Anda tidak perlu khawatir untuk membersihkannya - waktu proses akan melakukannya untuk Anda.

CLR mengatur heap terkelola menjadi beberapa generasi. Tiga generasi yang mengatur heap terkelola adalah: Generasi 0, Generasi 1, dan Generasi 2. GC mahir dalam mengambil kembali memori yang ditempati oleh objek yang dikelola. Namun, Anda harus mengikuti pedoman tertentu untuk memfasilitasi pengumpulan sampah lebih cepat untuk meningkatkan kinerja aplikasi Anda.

Haruskah saya menggunakan metode GC.Collect ()?

Pertama, apakah Anda benar-benar perlu memanggil GC.Collect dalam kode aplikasi Anda? Jawabannya dalam banyak kasus adalah tidak. Izinkan saya sekarang memberi tahu Anda apa yang dilakukan metode ini dan mengapa Anda harus menahan diri untuk tidak memanggil metode ini dalam banyak kasus.

Saat Anda melakukan panggilan ke metode GC.Collect (), runtime melakukan stack walk untuk menentukan objek yang bisa dijangkau dan yang tidak. Itu juga membekukan utas utama (dan juga utas anak apa pun yang dibuatnya) dari aplikasi. Dengan kata lain, ketika metode GC.Collect () dipanggil, runtime melakukan pengumpulan sampah pemblokiran dari semua generasi.

Saya selalu memilih untuk tidak menggunakan GC.Collect () kecuali ada alasan khusus untuk menggunakannya. GC biasanya terdiri dari fase Tandai dan Sapu yang diikuti oleh fase Pemadatan. Waktu yang dihabiskan oleh runtime untuk melakukan GC mungkin menjadi hambatan, jadi, gunakan sangat jarang dan jika Anda benar-benar perlu. Rico Mariani menyatakan: "Pertimbangkan untuk memanggil GC.Collect () jika beberapa peristiwa yang tidak berulang baru saja terjadi dan peristiwa ini kemungkinan besar telah menyebabkan banyak objek lama mati."

Menggunakan metode GC.Collect ()

Inilah cara Anda dapat memanggil metode GC.Collect () di kode Anda.

GC.Collect();

Perhatikan bahwa Anda juga dapat mengumpulkan objek yang berkaitan dengan generasi tertentu.

GC.Collect() - Digunakan untuk mengumpulkan benda-benda yang ada di generasi 0, 1, 2

GC.Collect(0) - digunakan untuk mengumpulkan benda-benda yang ada di generasi 0

GC.Collect(1) - digunakan untuk mengumpulkan objek yang ada di generasi 0 dan

Anda juga bisa menentukan berapa banyak memori yang telah dibebaskan dengan melakukan panggilan ke metode GC.Collect (). Untuk melakukan ini, Anda dapat memanfaatkan metode System.GC.GetTotalMemory () seperti yang ditunjukkan pada cuplikan kode di bawah ini.

//Write code to create some large objects here

Console.WriteLine("Total available memory before collection: {0:N0}", System.GC.GetTotalMemory(false));

System.GC.Collect();

Console.WriteLine("Total available memory collection: {0:N0}", System.GC.GetTotalMemory(true));

Metode GC.GetGeneration () dapat digunakan untuk mengetahui generasi yang dimiliki suatu objek. Lihat daftar kode yang diberikan di bawah ini.

static void Main(string[] args)

       {

           List obj = new List() { "Joydip", "Steve" };

           Console.WriteLine(System.GC.GetGeneration(obj));

           System.GC.Collect();

           Console.WriteLine(System.GC.GetGeneration(obj));

           System.GC.Collect();

           Console.WriteLine(System.GC.GetGeneration(obj));

           Console.Read();

       }

Saat Anda menjalankan program di atas, inilah yang dicetak di jendela konsol.

0

1

2

Seperti yang Anda lihat, setiap panggilan ke metode GC.Collect () mempromosikan objek "obj" ke generasi berikutnya yang lebih tinggi. Ini karena objek "obj" bertahan dari pengumpulan sampah di masing-masing dua kasus, yaitu, tidak diambil kembali dalam salah satu dari dua panggilan yang dilakukan ke metode GC.Collect ().

Anda bisa memaksa pengumpulan sampah baik untuk ketiga generasi atau ke generasi tertentu menggunakan metode GC.Collect (). Metode GC.Collect () kelebihan beban - Anda dapat memanggilnya tanpa parameter apa pun atau bahkan dengan meneruskan nomor pembuatan yang Anda inginkan ke pengumpul sampah untuk dikumpulkan.

Perhatikan bahwa objek yang memiliki finalizer (dan jika panggilan ke metode SuppressFinalize belum dilakukan) tidak akan dikumpulkan saat panggilan ke metode GC.Collect () dilakukan. Sebaliknya, objek tersebut akan ditempatkan dalam antrian finalisasi. Jika Anda ingin mengumpulkan objek-objek itu juga, Anda perlu membuat panggilan ke metode GC.WaitForPendingFinalizers () sehingga objek-objek itu dibersihkan ketika siklus GC berikutnya berjalan. Intinya, mengklaim kembali memori yang ditempati oleh objek yang telah diimplementasikan finalisator memerlukan dua lintasan karena objek tersebut ditempatkan dalam antrean finalisasi daripada diambil kembali di lintasan pertama saat pengumpul sampah berjalan.