到底什么是非托管资源?

发布于 2024-09-13 04:45:15 字数 30 浏览 10 评论 0原文

我想了解非托管资源。 谁能给我一个基本想法吗?

I want to know about unmanaged resources.
Can anyone please give me a basic idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

岛歌少女 2024-09-20 04:45:15

托管资源基本上意味着由垃圾收集器管理的“托管内存”。当您不再有任何对托管对象(使用托管内存)的引用时,垃圾收集器将(最终)为您释放该内存。

非托管资源就是垃圾收集器不知道的所有资源。例如:

  • 打开文件
  • 打开网络连接
  • 非托管内存
  • 在 XNA 中:顶点缓冲区、索引缓冲区、纹理等。

通常,您希望在丢失对管理对象的所有引用之前释放这些非托管资源他们。您可以通过在该对象上调用 Dispose 来完成此操作,或者(在 C# 中)使用 using 语句来执行此操作,该语句将为您处理调用 Dispose

如果您忽略了正确地Dispose非托管资源,那么当包含该资源的对象被垃圾收集时,垃圾收集器最终会为您处理它(这就是“终结”)。但是,由于垃圾收集器不了解非托管资源,因此它无法判断需要释放它们的迫切程度 - 因此您的程序可能会表现不佳或完全耗尽资源。

如果您自己实现一个处理非托管资源的类,则需要您正确实现 DisposeFinalize

Managed resources basically means "managed memory" that is managed by the garbage collector. When you no longer have any references to a managed object (which uses managed memory), the garbage collector will (eventually) release that memory for you.

Unmanaged resources are then everything that the garbage collector does not know about. For example:

  • Open files
  • Open network connections
  • Unmanaged memory
  • In XNA: vertex buffers, index buffers, textures, etc.

Normally you want to release those unmanaged resources before you lose all the references you have to the object managing them. You do this by calling Dispose on that object, or (in C#) using the using statement which will handle calling Dispose for you.

If you neglect to Dispose of your unmanaged resources correctly, the garbage collector will eventually handle it for you when the object containing that resource is garbage collected (this is "finalization"). But because the garbage collector doesn't know about the unmanaged resources, it can't tell how badly it needs to release them - so it's possible for your program to perform poorly or run out of resources entirely.

If you implement a class yourself that handles unmanaged resources, it is up to you to implement Dispose and Finalize correctly.

蓝天 2024-09-20 04:45:15

一些用户在托管资源中对打开的文件、数据库连接、分配的内存、位图、文件流等进行排名,而另一些则在非托管资源中进行排名。 那么它们是托管的还是非托管的?

我的观点是,响应更为复杂:当您在 .NET 中打开文件时,您可能会使用一些内置的 .NET 类 System.IO.File、FileStream或其他东西。因为它是一个普通的 .NET 类,所以它是托管的。但它是一个包装器,其内部执行真正打开文件的“脏工作”(使用 Win32 dll 与操作系统通信,调用低级函数甚至汇编指令)。这是 .NET 所不知道的,非托管的。
但您也许可以使用汇编指令自行打开该文件并绕过 .NET 文件函数。那么句柄和打开的文件都是非托管资源。

与 DB 相同:如果您使用某些 DB 程序集,则您有 DbConnection 等类,它们是 .NET 已知的并受管理。但它们包装了“肮脏的工作”,这是不受管理的(在服务器上分配内存,与其建立连接,......)。
如果您不使用这个包装类并自己打开一些网络套接字并使用一些命令与您自己的奇怪数据库进行通信,那么它是非托管的。

这些包装器类(File、DbConnection 等)是托管的,但如果您不使用包装器并自己做“肮脏的工作”,它们内部会以与您相同的方式使用非托管资源。因此,这些包装器确实实现了 Dispose/Finalize 模式。他们的责任是允许程序员在不再需要包装器时释放非托管资源,并在包装​​器被垃圾收集时释放它们。包装器将被垃圾收集器正确收集,但内部的非托管资源将使用 Dispose/Finalize 模式进行收集。

如果您不使用内置的 .NET 或第 3 方包装类并通过类中的某些汇编程序指令等打开文件,则这些打开的文件是非托管的,您必须实现处置/终结模式。如果不这样做,即使您不再使用它(文件操作完成),甚至在应用程序终止后,也会出现内存泄漏、永远锁定资源等情况。

但您的责任也在使用这些包装纸时。对于那些实现 dispose/finalise 的人(您认识它们,他们实现了 IDisposable),还实现您的 dispose/finalise 模式,甚至处理这些包装器或向它们发出信号以释放其非托管资源。如果不这样做,资源将在一段不确定的时间后被释放,但立即释放它是干净的(立即关闭文件,而不是使其保持打开状态并随机阻塞几分钟/小时)。因此,在类的 Dispose 方法中,您调用所有使用的包装器的 Dispose 方法。

Some users rank open files, db connections, allocated memory, bitmaps, file streams etc. among managed resources, others among unmanaged. So are they managed or unmanaged?

My opinion is, that the response is more complex: When you open file in .NET, you probably use some built-in .NET class System.IO.File, FileStream or something else. Because it is a normal .NET class, it is managed. But it is a wrapper, which inside does the "dirty work" (communicates with the operating system using Win32 dlls, calling low level functions or even assembler instructions) which really open the file. And this is, what .NET doesn't know about, unmanaged.
But you perhaps can open the file by yourself using assembler instructions and bypass .NET file functions. Then the handle and the open file are unmanaged resources.

The same with the DB: If you use some DB assembly, you have classes like DbConnection etc., they are known to .NET and managed. But they wrap the "dirty work", which is unmanaged (allocate memory on server, establish connection with it, ...).
If you don't use this wrapper class and open some network socket by yourself and communicate with your own strange database using some commands, it is unmanaged.

These wrapper classes (File, DbConnection etc.) are managed, but they inside use unmanaged resources the same way like you, if you don't use the wrappers and do the "dirty work" by yourself. And therefore these wrappers DO implement Dispose/Finalize patterns. It is their responsibility to allow programmer to release unmanaged resources when the wrapper is not needed anymore, and to release them when the wrapper is garbage collected. The wrapper will be correctly garbage collected by garbage collector, but the unmanaged resources inside will be collected by using the Dispose/Finalize pattern.

If you don't use built-in .NET or 3rd party wrapper classes and open files by some assembler instructions etc. in your class, these open files are unmanaged and you MUST implement dispose/finalise pattern. If you don't, there will be memory leak, forever locked resource etc. even when you don't use it anymore (file operation complete) or even after you application terminates.

But your responsibility is also when using these wrappers. For those, which implement dispose/finalise (you recognize them, that they implement IDisposable), implement also your dispose/finalise pattern and Dispose even these wrappers or give them signal to release their unmanaged resources. If you don't, the resources will be after some indefinite time released, but it is clean to release it immediately (close the file immediately and not leaving it open and blocked for random several minutes/hours). So in your class's Dispose method you call Dispose methods of all your used wrappers.

偏闹i 2024-09-20 04:45:15

非托管资源是指在 .NET 运行时 (CLR) 之外运行的资源(也称为非 .NET 代码)。例如,对 Win32 API 中的 DLL 的调用,或对用 C++ 编写的 .dll 的调用。

Unmanaged resources are those that run outside the .NET runtime (CLR)(aka non-.NET code.) For example, a call to a DLL in the Win32 API, or a call to a .dll written in C++.

烟沫凡尘 2024-09-20 04:45:15

“非托管资源”不是一个东西,而是一种责任。如果一个对象拥有非托管资源,则意味着 (1) 其外部的某些实体已被操纵,如果不清理,可能会导致问题,并且 (2) 该对象具有执行此类清理所需的信息并负责因为这样做。

尽管许多类型的非托管资源与各种类型的操作系统实体(文件、GDI 句柄、分配的内存块等)密切相关,但除了以下责任之外,没有单一类型的实体可以由所有这些实体共享。清理。通常,如果一个对象有责任执行清理,它将有一个 Dispose 方法,指示它执行它负责的所有清理。

在某些情况下,对象会考虑到在没有任何人先调用 Dispose 的情况下它们可能被丢弃的可能性。 GC 允许对象请求它们已被放弃的通知(通过调用名为 Finalize 的例程),并且对象可以使用此通知自行执行清理。

不幸的是,不同的人使用“托管资源”和“非托管资源”等术语来表示不同的含义。坦率地认为,从对象角度考虑更有用,因为要么不具有任何清理责任,要么具有仅在调用 Dispose 时才会处理的清理责任,要么具有应通过 Dispose 处理的清理责任,但可以也由 Finalize 处理。

An "unmanaged resource" is not a thing, but a responsibility. If an object owns an unmanaged resource, that means that (1) some entity outside it has been manipulated in a way that may cause problems if not cleaned up, and (2) the object has the information necessary to perform such cleanup and is responsible for doing it.

Although many types of unmanaged resources are very strongly associated with various type of operating-system entities (files, GDI handles, allocated memory blocks, etc.) there is no single type of entity which is shared by all of them other than the responsibility of cleanup. Typically, if an object either has a responsibility to perform cleanup, it will have a Dispose method which instructs it to carry out all cleanup for which it is responsible.

In some cases, objects will make allowances for the possibility that they might be abandoned without anyone having called Dispose first. The GC allows objects to request notification that they've been abandoned (by calling a routine called Finalize), and objects may use this notification to perform cleanup themselves.

Terms like "managed resource" and "unmanaged resource" are, unfortunately, used by different people to mean different things; frankly think it's more useful to think in terms of objects as either not having any cleanup responsibility, having cleanup responsibility that will only be taken care of if Dispose is called, or having cleanup responsibility which should be taken care of via Dispose, but which can also be taken care of by Finalize.

无人问我粥可暖 2024-09-20 04:45:15

托管资源和非托管资源之间的基本区别在于
垃圾收集器在某个时间点了解所有托管资源
GC 将清理所有相关的内存和资源
与托管对象。 GC 不知道非托管资源,例如
作为文件、流和句柄,所以如果你不明确地清理它们
你的代码最终会导致内存泄漏和资源锁定。

盗自此处,请随意阅读整篇文章。

The basic difference between a managed and unmanaged resource is that the
garbage collector knows about all managed resources, at some point in time
the GC will come along and clean up all the memory and resources associated
with a managed object. The GC does not know about unmanaged resources, such
as files, stream and handles, so if you do not clean them up explicitly in
your code then you will end up with memory leaks and locked resources.

Stolen from here, feel free to read the entire post.

森林散布 2024-09-20 04:45:15

在 .NET 托管堆中分配内存的任何资源都是托管资源。 CLR 完全了解这种内存,并将尽一切努力确保它不会成为孤儿。其他任何事情都是不受管理的。例如,与 COM 互操作,可能会在进程内存空间中创建对象,但 CLR 不会处理它。在这种情况下,跨托管边界进行调用的托管对象应该对超出托管边界的任何事情负责。

Any resource for which memory is allocated in the .NET managed heap is a Managed resource. CLR is completly aware of this sort of memory and will do everything to make sure that it doesn't go orphaned. Anything else is unmanaged. For example interoping with COM, might create objects in the proces memory space, but CLR will not take care of it. In this case the managed object that makes calls across the managed boundry should own the responsibility for anything beyond it.

深海里的那抹蓝 2024-09-20 04:45:15

让我们首先了解VB6或C++程序(非Dotnet应用程序)是如何执行的。
我们知道计算机只能理解机器级代码。机器级代码也称为本机代码或二进制代码。因此,当我们执行VB6或C++程序时,各自语言的编译器会将各自语言的源代码编译为本机代码,然后底层操作系统和硬件可以理解。

本机代码(非托管代码)特定于生成它的操作系统(本机)。如果您使用此已编译的本机代码并尝试在另一个操作系统上运行,它将失败。因此,这种程序执行方式的问题在于,它不能从一个平台移植到另一个平台。

现在让我们了解 .Net 程序是如何执行的。使用 dotnet 我们可以创建不同类型的应用程序。一些常见的 .NET 应用程序类型包括 Web、Windows、控制台和移动应用程序。无论应用程序的类型如何,当您执行任何 .NET 应用程序时,都会发生以下情况

  1. .NET 应用程序被编译为中间语言 (IL)。 IL 也称为通用中间语言 (CIL) 和 Microsoft 中间语言 (MSIL)。 .NET 和非 .NET 应用程序都会生成程序集。程序集的扩展名为.DLL 或.EXE。例如,如果您编译 Windows 或控制台应用程序,您会得到一个 .EXE,而当我们编译 Web 或类库项目时,我们会得到一个 .DLL。 .NET 和非 .NET 程序集之间的区别在于,DOTNET 程序集采用中间语言格式,而 NON DOTNET 程序集采用本机代码格式。

  2. 非 DOTNET 应用程序可以直接在操作系统之上运行,而 DOTNET 应用程序则在称为公共语言运行时 (CLR) 的虚拟环境之上运行。 CLR 包含一个称为即时编译器 (JIT) 的组件,它将中间语言转换为底层操作系统可以理解的本机代码。

因此,在 .NET 中,应用程序执行由 2 个步骤组成
1. 语言编译器,将源代码编译为中间语言(IL)
2. CLR 中的 JIT 编译器将 IL 转换为本机代码,然后可以在底层操作系统上运行。

由于 .NET 程序集采用中间语言格式而不是本机代码,因此只要目标平台具有公共语言运行时 (CLR),.NET 程序集就可以移植到任何平台。目标平台的 CLR 将 Intermedaite Language 转换为底层操作系统可以理解的本机代码。中间语言也称为托管代码。这是因为 CLR 管理在其中运行的代码。例如,在 VB6 程序中,开发人员负责取消分配对象消耗的内存。如果程序员忘记取消分配内存,我们可能会遇到难以检测的内存不足异常。另一方面,.NET 程序员不必担心取消分配对象消耗的内存。自动内存管理,也称为抓取收集,由 CLR 提供。除了垃圾收集之外,CLR 还提供了其他一些好处,我们将在稍后的会议中讨论这些好处。由于CLR管理和执行中间语言,因此它(IL)也称为托管代码。

.NET 支持不同的编程语言,例如 C#、VB、J# 和 C++。 C#、VB 和 J# 只能生成托管代码 (IL),而 C++ 既可以生成托管代码 (IL) 也可以生成非托管代码(本机代码)。

本机代码不会永久存储在任何地方,在我们关闭程序后,本机代码将被丢弃。当我们再次执行该程序时,本机代码将再次生成。

.NET程序的执行与java程序类似。在java中,我们有字节码和JVM(Java虚拟机),而在.NET中,我们有中间语言和CLR(公共语言运行时),

这是从此链接提供的 - 他是一位很棒的导师。
http://csharp-video- tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

Let us first understand how VB6 or C++ programs (Non Dotnet applications) used to execute.
We know that computers only understand machine level code. Machine level code is also called as native or binary code. So, when we execute a VB6 or C++ program, the respective language compiler, compiles the respective language source code into native code, which can then be understood by the underlying operating system and hardware.

Native code (Unmanaged Code) is specific (native) to the operating system on which it is generated. If you take this compiled native code and try to run on another operating system it will fail. So the problem with this style of program execution is that, it is not portable from one platform to another platform.

Let us now understand, how a .Net program executes. Using dotnet we can create different types of applications. A few of the common types of .NET applications include Web, Windows, Console and Mobile Applications. Irrespective of the type of the application, when you execute any .NET application the following happens

  1. The .NET application gets compiled into Intermediate language (IL). IL is also referred as Common Intermediate language (CIL) and Microsoft Intermediate language (MSIL). Both .NET and non .NET applications generate an assembly. Assemblies have an extension of .DLL or .EXE. For example if you compile a windows or Console application, you get a .EXE, where as when we compile a web or Class library project we get a .DLL. The difference between a .NET and NON .NET assembly is that, DOTNET Assembly is in intermediate language format where as NON DOTNET assembly is in native code format.

  2. NON DOTNET applications can run directly on top of the operating system, where as DOTNET applications run on top of a virtual environment called as Common Language Runtime (CLR). CLR contains a component called Just In-Time Compiler (JIT), which will convert the Intermediate language into native code which the underlying operating system can understand.

So, in .NET the application execution consists of 2 steps
1. Language compiler, compiles the Source Code into Intermediate Language (IL)
2. JIT compiler in CLR converts, the IL into native code which can then be run on the underlying operating system.

Since, a .NET assembly is in Intermedaite Language format and not native code, .NET assemblies are portable to any platform, as long as the target platform has the Common Language Runtime (CLR). The target platform's CLR converts the Intermedaite Language into native code that the underlying operating system can understand. Intermediate Languge is also called as managed code. This is because CLR manages the code that runs inside it. For example, in a VB6 program, the developer is responsible for de-allocating the memory consumed by an object. If a programmer forgets to de-allocate memory, we may run into hard to detecct out of memory exceptions. On the other hand a .NET programmer need not worry about de-allocating the memory consumed by an object. Automatic memory management, also known as grabage collection is provided by CLR. Apart, from garbage collection, there are several other benefits provided by the CLR, which we will discuss in a later session. Since, CLR is managing and executing the Intermediate Language, it (IL) is also called as managed code.

.NET supports different programming languages like C#, VB, J#, and C++. C#, VB, and J# can only generate managed code (IL), where as C++ can generate both managed code (IL) and un-managed code (Native code).

The native code is not stored permanently anywhere, after we close the program the native code is thrown awaya. When we execute the program again, the native code gets generated again.

.NET program is similar to java program execution. In java we have byte codes and JVM (Java Virtual Machine), where as in .NET we Intermediate Language and CLR (Common Language Runtime)

This is provided from this link - He is a great tutor.
http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

清醇 2024-09-20 04:45:15

非托管和托管资源基于应用程序域

根据我的理解,非托管资源是用于与应用程序域外部建立连接的所有资源。
它可能是您用来获取域外数据的 HttpClient 类,也可能是帮助您从文件读取/写入文件的 FileStream。

我们在工作完成后立即使用 Using 块来处理这些类对象,因为 GC 首先关心的是进程内部的资源不是外部的,尽管它最终会被 GC 处理。

Unmanaged and managed resources are based on application domain.

From my understanding, unmanaged resource is everything that is used to make connection to outside of your application domain.
It could be HttpClient class that you resort to fetch data outside of your domain or a FileStream that helps you to read/write from/to a file.

we use Using block to dispose these kind of classes objects immediately after our work is done because GC in the first place care about inside the process resources not outside ones, although it will be disposed by the GC at the end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文