Tôi muốn biết về tài nguyên không được quản lý. Bất cứ ai có thể xin vui lòng cho tôi một ý tưởng cơ bản?
Tôi muốn biết về tài nguyên không được quản lý. Bất cứ ai có thể xin vui lòng cho tôi một ý tưởng cơ bản?
Câu trả lời:
Tài nguyên được quản lý về cơ bản có nghĩa là "bộ nhớ được quản lý" được quản lý bởi trình thu gom rác. Khi bạn không còn bất kỳ tham chiếu nào đến một đối tượng được quản lý (sử dụng bộ nhớ được quản lý), trình thu gom rác sẽ (cuối cùng) sẽ giải phóng bộ nhớ đó cho bạn.
Tài nguyên không được quản lý là tất cả mọi thứ mà người thu gom rác không biết đến. Ví dụ:
Thông thường bạn muốn giải phóng những tài nguyên không được quản lý đó trước khi bạn mất tất cả các tài liệu tham khảo mà bạn có cho đối tượng quản lý chúng. Bạn làm điều này bằng cách gọi Dispose
vào đối tượng đó hoặc (trong C #) bằng cách sử dụng using
câu lệnh sẽ xử lý việc gọi Dispose
cho bạn.
Nếu bạn bỏ qua Dispose
chính xác các tài nguyên không được quản lý của mình, trình thu gom rác cuối cùng sẽ xử lý nó cho bạn khi đối tượng chứa tài nguyên đó là rác được thu thập (đây là "quyết toán"). Nhưng vì người thu gom rác không biết về các tài nguyên không được quản lý, nên nó không thể cho biết mức độ cần thiết để giải phóng chúng - vì vậy chương trình của bạn có thể hoạt động kém hoặc hết tài nguyên hoàn toàn.
Nếu bạn tự thực hiện một lớp xử lý các tài nguyên không được quản lý, thì việc bạn thực hiện Dispose
và Finalize
chính xác là tùy thuộc vào bạn .
Dispose
hoặc sử dụng using
.
IDisposable
. Nếu một lớp không thực hiện IDisposable
, sau đó bạn nên vứt bỏ các trường hợp mà lớp với using
hoặc Dispose()
khi bạn đang thực hiện với họ. Dựa trên điều này, converse của bạn giữ: Nếu một lớp thực hiện IDisposable
, thì nó có thể chứa các tài nguyên không được quản lý trong nội bộ.
Một số người dùng xếp hạng các tệp đang mở, kết nối db, bộ nhớ được phân bổ, bitmap, luồng tệp, v.v. trong số các tài nguyên được quản lý, những người khác trong số không được quản lý. Vì vậy, họ được quản lý hoặc không được quản lý?
Ý kiến của tôi là, phản hồi phức tạp hơn: Khi bạn mở tệp trong .NET, bạn có thể sử dụng một số lớp .NET tích hợp System.IO.File, FileStream hoặc một cái gì đó khác. Bởi vì nó là một lớp .NET bình thường, nó được quản lý. Nhưng nó là một trình bao bọc, bên trong thực hiện "công việc bẩn thỉu" (giao tiếp với hệ điều hành bằng cách sử dụng các dll Win32, gọi các hàm cấp thấp hoặc thậm chí các hướng dẫn trình biên dịch) thực sự mở tệp. Và đây là, những gì .NET không biết, không được quản lý. Nhưng có lẽ bạn có thể tự mở tệp bằng cách sử dụng hướng dẫn trình biên dịch và bỏ qua các chức năng tệp .NET. Sau đó, xử lý và các tập tin mở là tài nguyên không được quản lý.
Tương tự với DB: Nếu bạn sử dụng một số cụm DB, bạn có các lớp như DbConnection, v.v., chúng được biết đến với .NET và được quản lý. Nhưng họ bọc "công việc bẩn thỉu", không được quản lý (phân bổ bộ nhớ trên máy chủ, thiết lập kết nối với nó, ...). Nếu bạn không sử dụng lớp trình bao bọc này và tự mở một số ổ cắm mạng và liên lạc với cơ sở dữ liệu lạ của riêng bạn bằng một số lệnh, thì nó không được quản lý.
Các lớp trình bao bọc này (Tệp, DbConnection, v.v.) được quản lý, nhưng chúng bên trong sử dụng các tài nguyên không được quản lý theo cùng một cách như bạn, nếu bạn không sử dụng trình bao bọc và tự mình thực hiện "công việc bẩn". Và do đó, các hàm bao này thực hiện các mẫu Vứt bỏ / Hoàn thiện. Trách nhiệm của họ là cho phép lập trình viên giải phóng các tài nguyên không được quản lý khi không cần trình bao bọc nữa và giải phóng chúng khi trình bao bọc được thu gom rác. Trình bao bọc sẽ là rác chính xác được thu thập bởi người thu gom rác, nhưng các tài nguyên không được quản lý bên trong sẽ được thu thập bằng cách sử dụng mẫu Vứt bỏ / Hoàn thiện.
Nếu bạn không sử dụng các lớp trình bao bọc .NET hoặc bên thứ ba tích hợp và mở các tệp theo một số hướng dẫn trình biên dịch, v.v. trong lớp của bạn, các tệp mở này không được quản lý và bạn PHẢI triển khai mẫu xử lý / hoàn thiện. Nếu bạn không, sẽ có rò rỉ bộ nhớ, tài nguyên bị khóa vĩnh viễn, vv ngay cả khi bạn không sử dụng nó nữa (hoàn tất thao tác tệp) hoặc thậm chí sau khi ứng dụng của bạn chấm dứt.
Nhưng trách nhiệm của bạn cũng là khi sử dụng các hàm bao này. Đối với những người triển khai xử lý / hoàn thiện (bạn nhận ra họ, họ thực hiện IDis Dùng một lần), cũng triển khai mô hình xử lý / hoàn thiện của bạn và loại bỏ ngay cả các trình bao bọc này hoặc cung cấp cho họ tín hiệu để giải phóng tài nguyên không được quản lý của họ. Nếu bạn không, tài nguyên sẽ có sau một thời gian không xác định được phát hành, nhưng bạn có thể phát hành ngay lập tức (đóng tệp ngay lập tức và không để mở và bị chặn trong vài phút / giờ ngẫu nhiên). Vì vậy, trong phương thức Vứt bỏ lớp của bạn, bạn gọi các phương thức Vứt bỏ tất cả các hàm bao được sử dụng của bạn.
unmanaged vs managed resources
Một "tài nguyên không được quản lý" không phải là một thứ, mà là một trách nhiệm. Nếu một đối tượng sở hữu một tài nguyên không được quản lý, điều đó có nghĩa là (1) một thực thể bên ngoài nó đã bị thao túng theo cách có thể gây ra vấn đề nếu không được dọn sạch và (2) đối tượng có thông tin cần thiết để thực hiện việc dọn dẹp đó và chịu trách nhiệm để làm điều đó
Mặc dù nhiều loại tài nguyên không được quản lý có liên quan rất mạnh với nhiều loại thực thể hệ điều hành khác nhau (tệp, xử lý GDI, khối bộ nhớ được phân bổ, v.v.), không có loại thực thể nào được chia sẻ bởi tất cả chúng ngoài trách nhiệm của chúng dọn dẹp. Thông thường, nếu một đối tượng có trách nhiệm thực hiện việc dọn dẹp, nó sẽ có một phương thức Vứt bỏ để hướng dẫn nó thực hiện tất cả việc dọn dẹp mà nó chịu trách nhiệm.
Trong một số trường hợp, các đối tượng sẽ thực hiện trợ cấp cho khả năng chúng có thể bị bỏ rơi mà không có ai gọi là Vứt bỏ trước. GC cho phép các đối tượng yêu cầu thông báo rằng họ đã bị bỏ rơi (bằng cách gọi một thói quen gọi là Hoàn thiện) và các đối tượng có thể sử dụng thông báo này để tự thực hiện việc dọn dẹp.
Thật không may, các thuật ngữ như "tài nguyên được quản lý" và "tài nguyên không được quản lý", không may, được sử dụng bởi những người khác nhau có nghĩa là những thứ khác nhau; thẳng thắn nghĩ rằng sẽ hữu ích hơn khi nghĩ về các đối tượng là không có trách nhiệm dọn dẹp, có trách nhiệm dọn dẹp sẽ chỉ được quan tâm nếu Dispose được gọi, hoặc có trách nhiệm dọn dẹp cần được chăm sóc thông qua Vứt bỏ, nhưng có thể cũng được chăm sóc bởi Finalize.
Sự khác biệt cơ bản giữa tài nguyên được quản lý và không được quản lý là trình thu gom rác biết về tất cả các tài nguyên được quản lý, đến một lúc nào đó, GC sẽ xuất hiện và dọn sạch tất cả bộ nhớ và tài nguyên liên quan đến một đối tượng được quản lý. GC không biết về các tài nguyên không được quản lý, chẳng hạn như tệp, luồng và xử lý, vì vậy nếu bạn không dọn sạch chúng trong mã của mình thì bạn sẽ bị rò rỉ bộ nhớ và tài nguyên bị khóa.
Bị đánh cắp từ đây , hãy đọc toàn bộ bài viết.
Bất kỳ tài nguyên nào mà bộ nhớ được phân bổ trong heap được quản lý .NET đều là tài nguyên được quản lý. CLR hoàn toàn nhận thức được loại bộ nhớ này và sẽ làm mọi thứ để đảm bảo rằng nó không bị mồ côi. Bất cứ điều gì khác là không được quản lý. Ví dụ, xen kẽ với COM, có thể tạo các đối tượng trong không gian bộ nhớ, nhưng CLR sẽ không chăm sóc nó. Trong trường hợp này, đối tượng được quản lý thực hiện các cuộc gọi trên toàn bộ biên giới được quản lý phải chịu trách nhiệm cho bất kỳ điều gì ngoài nó.
Trước tiên chúng ta hãy hiểu cách các chương trình VB6 hoặc C ++ (ứng dụng Non Dotnet) được sử dụng để thực thi. Chúng tôi biết rằng máy tính chỉ hiểu mã cấp độ máy. Mã cấp độ máy cũng được gọi là mã gốc hoặc mã nhị phân. Vì vậy, khi chúng tôi thực hiện chương trình VB6 hoặc C ++, trình biên dịch ngôn ngữ tương ứng, biên dịch mã nguồn ngôn ngữ tương ứng thành mã gốc, sau đó có thể được hiểu bởi hệ điều hành và phần cứng bên dưới.
Mã riêng (Mã không được quản lý) là cụ thể (nguyên gốc) cho hệ điều hành mà nó được tạo. Nếu bạn lấy mã gốc được biên dịch này và cố gắng chạy trên một hệ điều hành khác, nó sẽ thất bại. Vì vậy, vấn đề với phong cách thực hiện chương trình này là, nó không thể di chuyển từ nền tảng này sang nền tảng khác.
Bây giờ chúng ta hãy hiểu, làm thế nào một chương trình .Net thực thi. Sử dụng dotnet chúng ta có thể tạo các loại ứng dụng khác nhau. Một số loại ứng dụng .NET phổ biến bao gồm Web, Windows, Console và Ứng dụng di động. Không phân biệt loại ứng dụng, khi bạn thực thi bất kỳ ứng dụng .NET nào, điều sau đây xảy ra
Ứng dụng .NET được biên dịch sang ngôn ngữ Trung cấp (IL). IL cũng được gọi là ngôn ngữ trung gian chung (CIL) và ngôn ngữ trung gian Microsoft (MSIL). Cả hai ứng dụng .NET và không .NET đều tạo ra một hội đồng. Các hội đồng có phần mở rộng là .DLL hoặc .EXE. Ví dụ: nếu bạn biên dịch một cửa sổ hoặc ứng dụng Console, bạn sẽ nhận được một .EXE, trong đó khi chúng tôi biên dịch một dự án thư viện web hoặc Class, chúng tôi nhận được một .DLL. Sự khác biệt giữa tập hợp .NET và NON .NET là ở chỗ, hội DOTNET có định dạng ngôn ngữ trung gian trong đó tập hợp NON DOTNET ở định dạng mã gốc.
Các ứng dụng NON DOTNET có thể chạy trực tiếp trên hệ điều hành, trong đó các ứng dụng DOTNET chạy trên môi trường ảo được gọi là Thời gian chạy ngôn ngữ chung (CLR). CLR chứa một thành phần được gọi là Trình biên dịch đúng lúc (JIT), sẽ chuyển đổi ngôn ngữ Trung gian thành mã gốc mà hệ điều hành cơ bản có thể hiểu được.
Vì vậy, trong .NET, việc thực thi ứng dụng bao gồm 2 bước 1. Trình biên dịch ngôn ngữ, biên dịch Mã nguồn thành Ngôn ngữ trung gian (IL) 2. Trình biên dịch JIT trong CLR chuyển đổi, IL thành mã gốc có thể chạy trên hệ điều hành cơ bản .
Vì, một cụm .NET có định dạng Ngôn ngữ Intermedaite chứ không phải mã gốc, các cụm .NET có thể di chuyển tới bất kỳ nền tảng nào, miễn là nền tảng đích có Thời gian chạy ngôn ngữ chung (CLR). CLR của nền tảng đích chuyển đổi Ngôn ngữ Intermedaite thành mã gốc mà hệ điều hành cơ bản có thể hiểu được. Languge trung gian cũng được gọi là mã được quản lý. Điều này là do CLR quản lý mã chạy bên trong nó. Ví dụ, trong một chương trình VB6, nhà phát triển chịu trách nhiệm phân bổ lại bộ nhớ mà một đối tượng sử dụng. Nếu một lập trình viên quên phân bổ bộ nhớ, chúng ta có thể gặp khó khăn trong việc loại bỏ các ngoại lệ của bộ nhớ. Mặt khác, một lập trình viên .NET không cần phải lo lắng về việc phân bổ lại bộ nhớ mà một đối tượng sử dụng. Quản lý bộ nhớ tự động, còn được gọi là bộ sưu tập snapage được cung cấp bởi CLR. Riêng biệt, từ bộ sưu tập rác, có một số lợi ích khác được cung cấp bởi CLR, mà chúng ta sẽ thảo luận trong phần sau. Vì, CLR đang quản lý và thực thi Ngôn ngữ trung gian, nên nó (IL) còn được gọi là mã được quản lý.
.NET hỗ trợ các ngôn ngữ lập trình khác nhau như C #, VB, J # và C ++. C #, VB và J # chỉ có thể tạo mã được quản lý (IL), trong đó C ++ có thể tạo cả mã được quản lý (IL) và mã không được quản lý (mã gốc).
Mã riêng không được lưu trữ vĩnh viễn ở bất cứ đâu, sau khi chúng tôi đóng chương trình, mã gốc sẽ bị loại bỏ. Khi chúng ta thực hiện lại chương trình, mã gốc sẽ được tạo lại.
Chương trình .NET tương tự như thực hiện chương trình java. Trong java, chúng ta có mã byte và JVM (Máy ảo Java), trong đó như trong .NET, chúng ta có Ngôn ngữ trung gian và CLR (Thời gian chạy ngôn ngữ chung)
Điều này được cung cấp từ liên kết này - Ông là một gia sư tuyệt vời. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execut-part-1.html