Sepertinya setiap buku .net berbicara tentang tipe nilai vs tipe referensi dan menjadikannya sebagai titik (sering salah) menyatakan di mana setiap tipe disimpan - heap atau stack. Biasanya ada di beberapa bab pertama dan disajikan sebagai fakta yang sangat penting. Saya pikir itu bahkan tercakup dalam ujian sertifikasi . Mengapa stack vs heap bahkan penting bagi (pemula). Pengembang net? Anda mengalokasikan barang dan hanya berfungsi, bukan?
36
Jawaban:
Saya menjadi yakin bahwa alasan utama informasi ini dianggap penting adalah tradisi. Dalam lingkungan yang tidak dikelola, perbedaan antara tumpukan dan tumpukan adalah penting dan kami harus mengalokasikan dan menghapus memori yang kami gunakan secara manual. Sekarang, pengumpulan sampah mengurus manajemen, sehingga mereka mengabaikan bagian itu. Saya tidak berpikir pesannya benar-benar telah melalui bahwa kita tidak perlu peduli jenis memori yang digunakan juga.
Seperti yang ditunjukkan oleh Fede, Eric Lippert memiliki beberapa hal yang sangat menarik untuk dikatakan tentang ini: http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx .
Mengingat informasi itu, Anda dapat menyesuaikan paragraf pertama saya dengan membaca: "Alasan orang memasukkan informasi ini dan menganggapnya penting adalah karena informasi yang salah atau tidak lengkap dikombinasikan dengan kebutuhan pengetahuan ini di masa lalu."
Bagi mereka yang berpikir itu masih penting untuk alasan kinerja: Tindakan apa yang akan Anda ambil untuk memindahkan sesuatu dari tumpukan ke tumpukan jika Anda mengukur sesuatu dan mengetahui bahwa itu penting? Kemungkinan besar, Anda akan menemukan cara yang sama sekali berbeda untuk meningkatkan kinerja untuk area masalah.
sumber
Aku sangat setuju; Saya melihat ini setiap waktu.
Salah satu bagian dari alasannya adalah karena banyak orang datang ke C # (atau bahasa .NET lainnya) dari latar belakang C atau C ++. Karena bahasa-bahasa itu tidak memberlakukan bagi Anda peraturan tentang masa penyimpanan, Anda diharuskan untuk mengetahui aturan-aturan itu dan mengimplementasikan program Anda dengan cermat untuk mengikutinya.
Sekarang, mengetahui aturan itu dan mengikutinya dalam C tidak mengharuskan Anda memahami "heap" dan "the stack". Tetapi jika Anda benar-benar mengerti bagaimana struktur data bekerja maka seringkali lebih mudah untuk memahami dan mengikuti aturan.
Ketika menulis buku pemula, wajar bagi penulis untuk menjelaskan konsep-konsep dalam urutan yang sama itu mereka pelajari. Itu belum tentu urutan yang masuk akal bagi pengguna. Saya baru-baru ini menjadi editor teknis untuk buku pemula C # 4 Scott Dorman, dan salah satu hal yang saya sukai adalah Scott memilih pemesanan yang cukup masuk akal untuk topik-topik tersebut, daripada memulai dengan topik yang sebenarnya cukup canggih dalam manajemen memori.
Bagian lain dari alasannya adalah bahwa beberapa halaman dalam dokumentasi MSDN sangat menekankan pertimbangan penyimpanan. Dokumentasi MSDN yang lebih tua yang masih berkeliaran sejak awal. Sebagian besar dokumentasi memiliki kesalahan kecil yang tidak pernah dihapuskan, dan Anda harus ingat bahwa itu ditulis pada waktu tertentu dalam sejarah dan untuk audiens tertentu.
Menurut saya, tidak. Yang jauh lebih penting untuk dipahami adalah hal-hal seperti:
Dan seterusnya.
Itu yang ideal.
Sekarang, ada situasi di mana itu penting. Pengumpulan sampah luar biasa dan relatif murah, tetapi tidak gratis. Menyalin struktur kecil di sekitar relatif murah, tetapi tidak gratis. Ada skenario kinerja realistis di mana Anda harus menyeimbangkan biaya tekanan pengumpulan dengan biaya menyalin berlebihan. Dalam kasus tersebut, sangat membantu untuk memiliki pemahaman yang kuat tentang ukuran, lokasi, dan masa pakai aktual semua memori yang relevan.
Demikian pula, ada skenario interop realistis di mana perlu untuk mengetahui apa yang ada di tumpukan dan apa yang ada di tumpukan, dan apa yang bisa dipindahkan oleh pengumpul sampah. Itu sebabnya C # memiliki fitur-fitur seperti "fix", "stackalloc" dan sebagainya.
Tapi itu semua adalah skenario tingkat lanjut. Idealnya seorang programmer pemula perlu khawatir tentang hal-hal ini.
sumber
Kalian semua kehilangan intinya. Alasan mengapa perbedaan tumpukan / tumpukan penting karena ruang lingkup .
Setelah x keluar dari ruang lingkup, objek yang dibuat akan hilang . Itu hanya karena dialokasikan pada tumpukan, bukan tumpukan. Tidak ada yang bisa masuk dalam bagian "..." dari metode yang dapat mengubah fakta itu. Secara khusus, setiap penugasan atau panggilan metode hanya bisa membuat salinan S struct, tidak membuat referensi baru untuk memungkinkannya tetap hidup.
Cerita yang sangat berbeda! Karena x sekarang ada di heap , objeknya (yaitu, objek itu sendiri , bukan salinannya) bisa sangat baik untuk terus hidup setelah x keluar dari ruang lingkup. Faktanya, satu-satunya cara ia tidak akan terus hidup adalah jika x adalah satu-satunya referensi untuk itu. Jika tugas atau metode panggilan di bagian "..." telah membuat referensi lain yang masih "hidup" pada saat x keluar dari ruang lingkup, maka objek itu akan terus hidup.
Itu adalah konsep yang sangat penting, dan satu-satunya cara untuk benar-benar memahami "apa dan mengapa" adalah mengetahui perbedaan antara tumpukan dan alokasi tumpukan.
sumber
...
dapat menyebabkanx
dikonversi ke bidang kelas yang dihasilkan kompiler, dan dengan demikian bertahan lebih lama dari ruang lingkup yang ditunjukkan. Secara pribadi, saya merasa tidak senang dengan gagasan untuk mengangkat secara implisit, tetapi perancang bahasa tampaknya mendukungnya (sebagai kebalikan dari keharusan bahwa setiap variabel yang diangkat memiliki sesuatu dalam deklarasi untuk menentukannya). Untuk memastikan kebenaran program, seringkali perlu memperhitungkan semua referensi yang mungkin ada pada suatu objek. Mengetahui bahwa pada saat suatu rutin kembali, tidak ada salinan referensi yang berlalu akan tetap berguna.structType foo
, lokasi penyimpananfoo
menyimpan konten bidangnya; jikafoo
ada di tumpukan, begitu juga bidangnya. Jikafoo
ada di heap, begitu juga bidangnya. jikafoo
ada dalam jaringan Apple II, begitu pula bidangnya. Sebaliknya, jikafoo
adalah tipe kelas, itu akan menampungnull
, atau referensi ke objek. Satu-satunya situasi di mana tipe kelasfoo
dapat dikatakan menahan bidang objek adalah jika itu adalah satu-satunya bidang kelas, dan memegang referensi untuk dirinya sendiri.Mengenai MENGAPA mereka membahas topik, saya setuju dengan @Kirk bahwa ini adalah konsep penting, yang harus Anda pahami. Semakin baik Anda mengetahui mekanismenya, semakin baik yang dapat Anda lakukan untuk membuat aplikasi hebat yang berkinerja lancar.
Sekarang Eric Lippert tampaknya setuju dengan Anda bahwa topik tersebut tidak dibahas dengan benar oleh sebagian besar penulis. Saya sarankan Anda membaca blog-nya untuk mencapai pemahaman yang bagus tentang apa yang ada di balik tudung.
sumber
Yah, saya pikir itulah inti dari lingkungan yang dikelola. Saya bahkan akan menyebut ini sebagai detail implementasi runtime yang mendasari bahwa Anda TIDAK boleh membuat asumsi, karena itu bisa berubah kapan saja.
Aku tidak tahu banyak tentang. JIT misalnya dapat melakukan analisis pelarian dan apa yang tidak dan tiba-tiba Anda akan memiliki benda-benda yang tergeletak di tumpukan atau hanya di beberapa register. Anda tidak dapat mengetahui hal ini.
Saya kira beberapa buku menutupinya hanya karena penulis menganggapnya sangat penting, atau karena mereka menganggap audiens mereka (misalnya jika Anda menulis "C # untuk programmer C ++" Anda mungkin harus membahas topik tersebut).
Meskipun demikian, saya pikir tidak banyak yang bisa dikatakan selain "memori dikelola". Kalau tidak, orang mungkin menarik kesimpulan yang salah.
sumber
Anda harus memahami bagaimana alokasi memori berfungsi untuk menggunakannya secara efisien bahkan jika Anda tidak harus mengelolanya secara eksplisit. Ini berlaku untuk hampir setiap abstraksi dalam ilmu komputer.
sumber
Mungkin ada beberapa kasus tepi di mana hal itu dapat membuat perbedaan. Ruang stack default adalah 1meg sementara heapnya beberapa manggung. Jadi, jika Anda memegang sejumlah besar objek, Anda dapat kehabisan ruang stack sambil memiliki banyak ruang tumpukan.
Namun, sebagian besar cukup akademis.
sumber
Seperti yang Anda katakan, C # seharusnya mengabstraksi manajemen memori, dan heap versus stack stack adalah detail implementasi yang menurut teori pengembang tidak perlu diketahui.
Masalahnya adalah beberapa hal sangat sulit dijelaskan dengan cara yang intuitif tanpa merujuk pada detail implementasi ini. Cobalah untuk menjelaskan perilaku yang dapat diobservasi ketika Anda memodifikasi tipe nilai yang bisa berubah - hampir tidak mungkin dilakukan tanpa merujuk pada perbedaan tumpukan / tumpukan. Atau coba jelaskan mengapa bahkan memiliki tipe nilai dalam bahasa di tempat pertama, dan kapan Anda akan menggunakannya? Anda perlu memahami perbedaan untuk memahami bahasa.
Perhatikan bahwa buku-buku tentang katakanlah Python atau JavaScript tidak membuat masalah besar jika mereka menyebutkannya. Ini karena semuanya baik tumpukan dialokasikan atau tidak berubah, yang berarti semantik menyalin tidak pernah ikut bermain. Dalam bahasa-bahasa itu, abstraksi memori berfungsi, dalam C # itu bocor.
sumber