Saya telah membaca tentang Generations and Large object heap. Tetapi saya masih gagal untuk memahami apa pentingnya (atau manfaat) memiliki tumpukan objek besar?
Apa yang bisa salah (dalam hal kinerja atau memori) jika CLR hanya mengandalkan Generasi 2 (Mengingat ambang batas untuk Gen0 dan Gen1 kecil untuk menangani objek Besar) untuk menyimpan objek besar?
.net
garbage-collection
clr
large-object-heap
Manish Basantani
sumber
sumber
Jawaban:
Pengumpulan sampah tidak hanya menyingkirkan objek yang tidak direferensikan, tetapi juga memadatkan heap. Itu pengoptimalan yang sangat penting. Ini tidak hanya membuat penggunaan memori lebih efisien (tidak ada lubang yang tidak digunakan), tetapi juga membuat cache CPU jauh lebih efisien. Cache adalah masalah yang sangat besar pada prosesor modern, mereka jauh lebih cepat daripada bus memori.
Pemadatan dilakukan hanya dengan menyalin byte. Namun itu membutuhkan waktu. Semakin besar objeknya, semakin besar kemungkinan biaya untuk menyalinnya melebihi kemungkinan peningkatan penggunaan cache CPU.
Jadi mereka menjalankan banyak tolok ukur untuk menentukan titik impas. Dan mencapai 85.000 byte sebagai titik potong di mana penyalinan tidak lagi meningkatkan kinerja. Dengan pengecualian khusus untuk array ganda, mereka dianggap 'besar' ketika array memiliki lebih dari 1000 elemen. Itu adalah pengoptimalan lain untuk kode 32-bit, pengalokasi tumpukan objek besar memiliki properti khusus yang mengalokasikan memori pada alamat yang disejajarkan dengan 8, tidak seperti pengalokasi generasi biasa yang hanya mengalokasikan selaras 4. Penyelarasan itu adalah masalah besar untuk ganda , membaca atau menulis tulisan ganda yang tidak sejajar sangat mahal. Anehnya info Microsoft yang jarang tidak pernah menyebutkan array yang panjang, tidak yakin ada apa dengan itu.
Fwiw, ada banyak kecemasan programmer tentang tumpukan objek yang besar tidak dipadatkan. Ini selalu dipicu ketika mereka menulis program yang menghabiskan lebih dari setengah dari seluruh ruang alamat yang tersedia. Dilanjutkan dengan menggunakan tool seperti memory profiler untuk mencari tahu mengapa program tersebut di-bomb meskipun masih banyak tersedia virtual memory yang tidak terpakai. Alat semacam itu menunjukkan lubang di LOH, potongan memori yang tidak terpakai di mana sebelumnya ada benda besar, tetapi sampah dikumpulkan. Begitulah harga LOH yang tak terelakkan, lubang hanya dapat digunakan kembali dengan alokasi untuk benda yang ukurannya sama atau lebih kecil. Masalah sebenarnya adalah mengasumsikan bahwa program harus diizinkan untuk menggunakan semua memori virtual kapan saja.
Masalah yang jika tidak hilang sepenuhnya hanya dengan menjalankan kode pada sistem operasi 64-bit. Proses 64-bit memiliki 8 terabyte ruang alamat memori virtual yang tersedia, 3 kali lipat lebih besar dari proses 32-bit. Anda tidak bisa kehabisan lubang.
Singkat cerita, LOH membuat kode berjalan lebih efisien. Dengan biaya penggunaan ruang alamat memori virtual yang tersedia kurang efisien.
UPDATE, .NET 4.5.1 sekarang mendukung pemadatan properti LOH, GCSettings.LargeObjectHeapCompactionMode . Berhati-hatilah dengan konsekuensinya.
sumber
Jika ukuran objek lebih besar dari beberapa nilai yang disematkan (85000 byte dalam .NET 1), maka CLR meletakkannya di Large Object Heap. Ini mengoptimalkan:
tidak pernahjarang dipadatkan)sumber
Perbedaan penting dari Small Object Heap (SOH) dan Large Object Heap (LOH) adalah, memori di SOH akan dipadatkan saat dikumpulkan, sedangkan LOH tidak, seperti artikel ini diilustrasikan dalam . Memadatkan benda besar membutuhkan banyak biaya. Mirip dengan contoh di artikel, katakanlah memindahkan satu byte dalam memori membutuhkan 2 siklus, kemudian memadatkan objek 8MB di komputer 2GHz membutuhkan 8ms, yang merupakan biaya yang besar. Mempertimbangkan objek besar (array dalam banyak kasus) cukup umum dalam praktiknya, saya kira itulah alasan mengapa Microsoft menyematkan objek besar di memori dan mengusulkan LOH.
BTW, menurut posting ini , LOH biasanya tidak menimbulkan masalah fragmen memori.
sumber
Prinsipnya adalah bahwa tidak mungkin (dan sangat mungkin desain yang buruk) bahwa suatu proses akan membuat banyak objek besar berumur pendek sehingga CLR mengalokasikan objek besar ke heap terpisah yang menjalankan GC pada jadwal yang berbeda dengan heap biasa. http://msdn.microsoft.com/en-us/magazine/cc534993.aspx
sumber
Saya bukan ahli CLR, tetapi saya membayangkan bahwa memiliki heap khusus untuk objek besar dapat mencegah penyapuan GC yang tidak perlu dari heap generasi yang ada. Mengalokasikan objek yang besar membutuhkan memori bebas yang berdekatan dalam jumlah yang signifikan . Untuk menyediakannya dari "lubang" yang tersebar di heap generasi, Anda memerlukan pemadatan yang sering (yang hanya dilakukan dengan siklus GC).
sumber