Apa sebenarnya sumber daya yang tidak dikelola?


160

Saya ingin tahu tentang sumber daya yang tidak dikelola. Adakah yang bisa tolong beri saya ide dasar?


Lihat juga halaman ini, yang memberikan penjelasan dan pola yang fantastis untuk penggunaan IDisposable yang tepat, dan bagaimana cara memperhitungkan sumber daya yang tidak dikelola: stackoverflow.com/questions/538060/…
Kyle Baran

Jawaban:


177

Sumber daya yang dikelola pada dasarnya berarti "memori yang dikelola" yang dikelola oleh pengumpul sampah. Ketika Anda tidak lagi memiliki referensi ke objek yang dikelola (yang menggunakan memori yang dikelola), pemulung akan (akhirnya) melepaskan memori itu untuk Anda.

Sumber daya yang tidak dikelola adalah segala sesuatu yang tidak diketahui oleh pemulung. Sebagai contoh:

  • Buka file
  • Buka koneksi jaringan
  • Memori yang tidak dikelola
  • Dalam XNA: buffer sudut, buffer indeks, tekstur, dll.

Biasanya Anda ingin melepaskan sumber daya yang tidak dikelola tersebut sebelum Anda kehilangan semua referensi yang Anda miliki untuk objek yang mengelolanya. Anda melakukan ini dengan memanggil Disposeobjek itu, atau (dalam C #) menggunakan usingpernyataan yang akan menangani panggilan Disposeuntuk Anda.

Jika Anda mengabaikan Disposesumber daya yang tidak dikelola dengan benar, pengumpul sampah pada akhirnya akan menanganinya untuk Anda ketika objek yang mengandung sumber daya itu adalah sampah yang dikumpulkan (ini adalah "finalisasi"). Tetapi karena pengumpul sampah tidak tahu tentang sumber daya yang tidak dikelola, ia tidak dapat mengatakan seberapa buruk ia harus melepaskannya - sehingga mungkin program Anda berkinerja buruk atau kehabisan sumber daya sepenuhnya.

Jika Anda menerapkan kelas sendiri yang menangani sumber daya yang tidak dikelola, terserah Anda untuk menerapkan Disposedan Finalizedengan benar.


7
Koneksi Open Database termasuk dalam kategori apa? Dikelola / Tidak dikelola?
Deviprasad Das

8
+1 Jawaban lain kehilangan poin penting yang Anda panggil Buang objek yang dikelola yang secara internal menangani pembebasan sumber daya yang tidak dikelola yang dibungkusnya (mis. Pegangan file, bit bit + GDI, ...) dan jika Anda mengakses sumber daya yang tidak dikelola secara langsung ( PInvoke dll.) Anda harus mengatasinya.
Ian Mercer

2
@Dev: Tidak dikelola - karena GC tidak mengetahuinya (dengan asumsi Anda tidak menggunakan beberapa basis data memori yang dikelola secara hipotetis). Tetapi objek koneksi itu sendiri mungkin tidak memiliki sumber daya yang tidak dikelola. Agaknya koneksi database menggunakan file terbuka atau koneksi jaringan di suatu tempat - tetapi ada kemungkinan bahwa objek lain (selain objek koneksi) menangani sumber daya yang tidak dikelola tersebut (mungkin pustaka basis data Anda membuat cache koneksi). Periksa dokumentasi dan lihat di mana ia meminta Anda menelepon Disposeatau menggunakan using.
Andrew Russell

11
Saya punya komentar dasar / pertanyaan tentang ini, dapatkah saya menghubungkan objek sebagai dikelola / tidak dikelola hanya dengan jenis, misalnya, string dikelola, DataSet tidak dikelola (itulah sebabnya ia memiliki metode Buang ()) , Koneksi basis data tidak dikelola (karena telah dibuang), dll. Jadi asumsinya, jika ia memiliki metode "Buang ()", maka itu tidak dikelola? Selain itu, apa yang akan menjadi objek XmlDocument? Terima kasih
ganders

15
@ penjaga Itu adalah aturan praktis yang bagus. Meskipun perlu diingat bahwa semua instance kelas C # adalah objek yang dikelola. Jika sebuah instance dari sebuah kelas dapat menampung sumber daya yang tidak dikelola, maka kelas itu harus diimplementasikan IDisposable. Jika suatu kelas benar- benar diterapkan IDisposable, maka Anda harus membuang instance kelas tersebut dengan usingatau Dispose()ketika Anda selesai menggunakannya. Berdasarkan hal ini, percakapan Anda berlaku: Jika suatu kelas mengimplementasikan IDisposable, maka kemungkinan ia menyimpan sumber daya yang tidak dikelola secara internal.
Andrew Russell

56

Beberapa pengguna memberi peringkat file terbuka, koneksi db, memori yang dialokasikan, bitmap, aliran file dll di antara sumber daya yang dikelola, yang lain di antara yang tidak dikelola. Jadi apakah mereka dikelola atau tidak dikelola?

Pendapat saya adalah, bahwa responsnya lebih kompleks: Ketika Anda membuka file di .NET, Anda mungkin menggunakan beberapa built-in .NET class System.IO.File, FileStream atau yang lainnya. Karena ini adalah kelas .NET yang normal, ini dikelola. Tapi itu adalah pembungkus, yang di dalamnya melakukan "pekerjaan kotor" (berkomunikasi dengan sistem operasi menggunakan Win32 dll, memanggil fungsi tingkat rendah atau bahkan instruksi assembler) yang benar-benar membuka file. Dan ini, yang .NET tidak tahu, tidak dikelola. Tapi Anda mungkin bisa membuka file sendiri menggunakan instruksi assembler dan memotong fungsi file .NET. Maka pegangan dan file yang terbuka adalah sumber daya yang tidak dikelola.

Sama dengan DB: Jika Anda menggunakan beberapa rakitan DB, Anda memiliki kelas seperti DbConnection dll., Mereka dikenal dengan .NET dan dikelola. Tetapi mereka membungkus "pekerjaan kotor", yang tidak dikelola (mengalokasikan memori pada server, membuat koneksi dengannya, ...). Jika Anda tidak menggunakan kelas pembungkus ini dan membuka beberapa soket jaringan sendiri dan berkomunikasi dengan database aneh Anda sendiri menggunakan beberapa perintah, itu tidak dikelola.

Kelas pembungkus ini (File, DbConnection dll.) Dikelola, tetapi mereka di dalamnya menggunakan sumber daya yang tidak dikelola dengan cara yang sama seperti Anda, jika Anda tidak menggunakan pembungkus dan melakukan "pekerjaan kotor" sendiri. Dan karenanya pembungkus ini TIDAK menerapkan pola Buang / Finalisasi. Merupakan tanggung jawab mereka untuk memungkinkan pemrogram untuk mengeluarkan sumber daya yang tidak dikelola ketika pembungkus tidak diperlukan lagi, dan untuk melepaskan mereka ketika pembungkusnya adalah sampah yang dikumpulkan. Pembungkus akan benar-benar sampah yang dikumpulkan oleh pengumpul sampah, tetapi sumber daya yang tidak dikelola di dalam akan dikumpulkan dengan menggunakan pola Buang / Selesaikan.

Jika Anda tidak menggunakan built-in .NET atau kelas pembungkus pihak ke-3 dan membuka file dengan beberapa instruksi assembler dll di kelas Anda, file-file terbuka ini tidak dikelola dan Anda HARUS menerapkan pola buang / finalisasi. Jika tidak, akan ada kebocoran memori, sumber daya terkunci selamanya, dll. Bahkan ketika Anda tidak menggunakannya lagi (operasi file selesai) atau bahkan setelah aplikasi Anda berakhir.

Tetapi tanggung jawab Anda juga saat menggunakan pembungkus ini. Bagi mereka, yang menerapkan membuang / menyelesaikan (Anda mengenalinya, bahwa mereka menerapkan IDisposable), menerapkan juga membuang / menyelesaikan pola Anda dan Buang bahkan pembungkus ini atau memberi mereka sinyal untuk melepaskan sumber daya mereka yang tidak dikelola. Jika Anda tidak, sumber daya akan setelah beberapa waktu tidak terbatas dirilis, tetapi bersih untuk segera melepaskannya (tutup file dengan segera dan tidak membiarkannya terbuka dan diblokir secara acak beberapa menit / jam). Jadi, dalam metode Buang kelas Anda, Anda memanggil metode Buang semua pembungkus bekas Anda.


1
Bagus pada kejelasan tambahan padaunmanaged vs managed resources
sekarang dia yang tidak boleh disebutkan namanya.

Terima kasih atas jawaban Anda. kelas mana yang direkomendasikan agar kita panggil Buang?
BKSpurgeon

2
Ini sederhana. Pada setiap kelas yang Anda gunakan, Anda harus memverifikasi, apakah itu mengimplementasikan antarmuka IDisposable. Jika ya, maka jika Anda menggunakan kelas tersebut dalam satu metode (mis: membuka file, menyimpan teks, menutup file), Anda dapat menggunakannya dengan pola () {}, yang memanggil Buang untuk Anda secara otomatis. Jika Anda menggunakan kelas tersebut dalam lebih banyak metode (misalnya: kelas Anda berisi File, di konstruktor itu membuka file, lalu beberapa metode menambahkan beberapa log ...), maka Anda harus mengimplementasikan antarmuka IDisposable oleh kelas Anda, menerapkan pola Buang / Selesaikan dan membuang objek kelas itu dengan benar.
Martas

1
"... beberapa built-in .NET class System.IO.File, FileStream atau yang lainnya. Karena ini adalah kelas normal .NET, dikelola." Dengan hormat, ini salah dan menyesatkan. Mereka tidak dikelola . Jika dikelola, maka Anda dapat mengalokasikan kelas-kelas ini dan mengharapkan pengumpul sampah untuk sepenuhnya menangani deallokasi semua sumber daya dengan cara deterministik. Namun, ini akan menyebabkan file menangani dan sumber daya yang tidak dikelola dikunci dan ditahan lebih lama dari yang diperlukan karena pengumpul sampah tidak akan membatalkan alokasi kelas, dan tidak menyelesaikannya untuk waktu yang sangat lama.
AaronLS

1
@AaronLS dalam komentar Anda, Anda berbicara tentang "FileStream" dengan menyebutnya sebagai tidak dikelola tetapi tidak, meskipun secara internal menggunakan sumber daya yang tidak dikelola untuk melakukan tugasnya. Di dunia yang dikelola, Microsoft telah menyembunyikan banyak hal yang tidak dikelola dari Anda dengan menerapkan buang pola. Kode yang dikelola tidak berarti tidak menggunakan sumber daya yang tidak dikelola. Namun, Microsoft telah melakukan pekerjaan yang baik dalam mengimplementasikan IDisposable pada jenis objek tersebut. Ini dibuktikan oleh fakta bahwa itu menerapkan IDisposable. Sehubungan dengan bukti itu, kita harus menganggapnya sebagai objek yang dikelola.
Malik Khalil

12

Sumber daya yang tidak dikelola adalah sumber daya yang dijalankan di luar .NET runtime (CLR) (alias kode non- .NET). Misalnya, panggilan ke DLL di Win32 API, atau panggilan ke .dll yang ditulis dalam C ++.


6

"Sumber daya yang tidak dikelola" bukanlah sesuatu, tetapi tanggung jawab. Jika suatu objek memiliki sumber daya yang tidak dikelola, itu berarti bahwa (1) beberapa entitas di luarnya telah dimanipulasi dengan cara yang dapat menyebabkan masalah jika tidak dibersihkan, dan (2) objek memiliki informasi yang diperlukan untuk melakukan pembersihan seperti itu dan bertanggung jawab untuk melakukannya.

Meskipun banyak jenis sumber daya yang tidak dikelola sangat terkait dengan berbagai jenis entitas sistem operasi (file, pegangan GDI, blok memori yang dialokasikan, dll.), Tidak ada satu jenis entitas pun yang dibagikan oleh mereka semua selain dari tanggung jawab membersihkan. Biasanya, jika suatu objek memiliki tanggung jawab untuk melakukan pembersihan, ia akan memiliki metode Buang yang memerintahkannya untuk melakukan semua pembersihan yang menjadi tanggung jawabnya.

Dalam beberapa kasus, objek akan membuat kelonggaran untuk kemungkinan bahwa mereka mungkin ditinggalkan tanpa ada yang memanggil Buang dulu. GC memungkinkan objek untuk meminta pemberitahuan bahwa mereka telah ditinggalkan (dengan memanggil rutin yang disebut Selesai), dan objek dapat menggunakan pemberitahuan ini untuk melakukan pembersihan sendiri.

Sayangnya, istilah seperti "sumber daya yang dikelola" dan "sumber daya yang tidak dikelola" digunakan oleh orang yang berbeda untuk mengartikan hal yang berbeda; terus terang berpikir itu lebih berguna untuk berpikir dalam hal objek baik tidak memiliki tanggung jawab pembersihan, memiliki tanggung jawab pembersihan yang hanya akan diurus jika Buang disebut, atau memiliki tanggung jawab pembersihan yang harus diurus melalui Buang, tetapi yang dapat juga diurus oleh Finalisasi.


5

Perbedaan mendasar antara sumber daya yang dikelola dan tidak dikelola adalah bahwa pemulung tahu tentang semua sumber daya yang dikelola, pada suatu saat GC akan datang dan membersihkan semua memori dan sumber daya yang terkait dengan objek yang dikelola. GC tidak tahu tentang sumber daya yang tidak dikelola, seperti file, streaming, dan pegangan, jadi jika Anda tidak membersihkannya secara eksplisit dalam kode Anda, maka Anda akan berakhir dengan kebocoran memori dan sumber daya yang terkunci.

Dicuri dari sini , silakan baca seluruh pos.


2

Sumber daya apa pun yang memori dialokasikan di tumpukan .NET dikelola adalah sumber daya yang dikelola. CLR sepenuhnya menyadari jenis memori ini dan akan melakukan segalanya untuk memastikan bahwa itu tidak menjadi yatim piatu. Ada lagi yang tidak dikelola. Misalnya interoping dengan COM, mungkin membuat objek dalam ruang memori proces, tetapi CLR tidak akan menanganinya. Dalam hal ini objek terkelola yang melakukan panggilan melintasi batas terkelola harus memiliki tanggung jawab atas apa pun di luarnya.


0

Mari kita memahami bagaimana program VB6 atau C ++ (aplikasi Non Dotnet) digunakan untuk mengeksekusi. Kita tahu bahwa komputer hanya memahami kode level mesin. Kode level mesin juga disebut sebagai kode asli atau biner. Jadi, ketika kita menjalankan program VB6 atau C ++, kompiler bahasa masing-masing, mengkompilasi kode sumber bahasa masing-masing ke dalam kode asli, yang kemudian dapat dipahami oleh sistem operasi dan perangkat keras yang mendasarinya.

Kode asli (Unmanaged Code) adalah spesifik (asli) ke sistem operasi yang dihasilkannya. Jika Anda mengambil kode asli yang dikompilasi ini dan mencoba menjalankannya pada sistem operasi lain, itu akan gagal. Jadi masalah dengan gaya pelaksanaan program ini adalah, tidak portabel dari satu platform ke platform lainnya.

Mari kita sekarang mengerti, bagaimana program .Net dijalankan. Menggunakan dotnet kita dapat membuat berbagai jenis aplikasi. Beberapa jenis aplikasi .NET yang umum termasuk Aplikasi Web, Windows, Konsol dan Mobile. Terlepas dari jenis aplikasi, ketika Anda menjalankan aplikasi .NET, hal berikut terjadi

  1. Aplikasi .NET dikompilasi ke dalam bahasa Intermediate (IL). IL juga disebut sebagai Common Intermediate Language (CIL) dan Microsoft Intermediate language (MSIL). Aplikasi .NET dan non .NET menghasilkan perakitan. Assemblies memiliki ekstensi .DLL atau .EXE. Sebagai contoh jika Anda mengkompilasi aplikasi windows atau konsol, Anda mendapatkan .EXE, di mana ketika kita mengkompilasi proyek perpustakaan web atau kelas kita mendapatkan .DLL. Perbedaan antara rakitan .NET dan NON .NET adalah bahwa, Rakitan DOTNET dalam format bahasa menengah di mana rakitan NON DOTNET dalam format kode asli.

  2. Aplikasi NON DOTNET dapat berjalan langsung di atas sistem operasi, sedangkan aplikasi DOTNET berjalan di atas lingkungan virtual yang disebut Common Language Runtime (CLR). CLR berisi komponen yang disebut Just In-Time Compiler (JIT), yang akan mengubah bahasa Menengah menjadi kode asli yang dapat dipahami oleh sistem operasi yang mendasarinya.

Jadi, dalam. NET eksekusi aplikasi terdiri dari 2 langkah 1. Pengkompilasi bahasa, mengkompilasi Kode Sumber ke Bahasa Intermediate (IL) 2. Kompiler JIT dalam konversi CLR, IL menjadi kode asli yang kemudian dapat dijalankan pada sistem operasi yang mendasarinya .

Karena, .NET assembly dalam format Bahasa Intermedaite dan bukan kode asli, .NET assemblets mudah dibawa ke platform apa pun, asalkan platform target memiliki Common Language Runtime (CLR). CLR platform target mengubah Bahasa Intermedaite menjadi kode asli yang dapat dimengerti oleh sistem operasi yang mendasarinya. Languge Menengah juga disebut sebagai kode terkelola. Ini karena CLR mengelola kode yang berjalan di dalamnya. Misalnya, dalam program VB6, pengembang bertanggung jawab untuk mengalokasikan memori yang dikonsumsi oleh suatu objek. Jika seorang programmer lupa untuk mendelegasikan memori, kita mungkin mengalami kesulitan untuk mendeteksi pengecualian memori. Di sisi lain. NET programmer tidak perlu khawatir tentang de-alokasi memori yang dikonsumsi oleh suatu objek. Manajemen memori otomatis, juga dikenal sebagai koleksi grabage disediakan oleh CLR. Selain, dari pengumpulan sampah, ada beberapa manfaat lain yang disediakan oleh CLR, yang akan kita bahas di sesi selanjutnya. Karena, CLR mengelola dan mengeksekusi Bahasa Menengah, itu (IL) juga disebut sebagai kode terkelola.

.NET mendukung berbagai bahasa pemrograman seperti C #, VB, J #, dan C ++. C #, VB, dan J # hanya dapat menghasilkan kode terkelola (IL), sedangkan C ++ dapat menghasilkan kode terkelola (IL) dan kode tidak terkelola (kode asli).

Kode asli tidak disimpan secara permanen di mana pun, setelah kita menutup program kode asli dilemparkan awaya. Ketika kami menjalankan program lagi, kode asli akan dihasilkan lagi.

Program .NET mirip dengan eksekusi program java. Di java kita punya kode byte dan JVM (Java Virtual Machine), sedangkan di .NET kita Intermediate Language dan CLR (Common Language Runtime)

Ini disediakan dari tautan ini - Dia adalah guru yang hebat. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.