首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从类创建的角度看托管资源与非托管资源

从类创建的角度看托管资源与非托管资源
EN

Stack Overflow用户
提问于 2018-10-25 01:13:01
回答 1查看 55关注 0票数 0

我想要理解的是,当我创建自己的类时,我如何知道什么是托管资源,什么是非托管资源,这样我才能知道我的类是否需要提供清理它的能力,或者GC最终是否会这样做。此外,再深入一点,当我创建一个.Dispose()方法时,将有一个用于托管资源的块和一个用于非托管资源的块,以及我如何知道应该在哪个块中清理哪些资源。

我在C#程序中读到了许多关于托管资源和非托管资源的答案,但其中大多数都提供了关于GC清理的定义,如“托管资源由GC清理,而非托管资源不是”。这对我没有帮助,因为我看不到GC如何确定它将清理什么以及它将留下什么。我也知道,如果一个类提供了一个.Dispose()方法,我的程序就应该执行它。

我看到的答案表明,如果我使用WIN32应用程序接口,我已经创建了一个非托管资源。如果我不调用WIN32应用程序接口,这是否意味着我没有任何非托管资源?我也遇到过马歇尔。马歇尔是否也创建非托管资源?是否有其他“关键字/类”可用于识别我正在创建非托管资源?

请在您的回答中排除任何有关“占用大量内存的托管资源”的内容。我知道能够释放内存是很好的,但这并不是必需的,因为GC最终会这样做,只是不总是及时的。

EN

回答 1

Stack Overflow用户

发布于 2018-10-25 08:31:48

通常,如果您不跨越本机代码和托管代码的界限,则不必费心在类中释放非托管资源。

当您运行.NET应用程序时,框架在内存中为它分配一个托管片,您可以从.NET框架访问的几乎所有内容都将由GC存储和跟踪。其他所有东西都落在这个切片之外,没有GC敏锐的眼睛。

因此,对于GC如何确定哪些资源应该收集,哪些不应该收集的问题,简短的答案是它不知道任何关于非托管资源的信息,所以它也无法收集这些资源。

这些世界-本机和托管-是分开的,但它们可以相互通信,这就是编组的用途。你可以阅读更多关于它的here。当然,您可以创建非托管资源,但这并不意味着每次使用它时都会这样做。

说每次使用Win32 API时,都会创建必须发布的本机资源,这也有点极端。当您使用Platform InvokeC++/CLI wrapper调用任何本地代码时,这些本地代码创建的指针或任何应该在本地手动释放的内容(这些当然不会被GC跟踪),如果它们尚未由本地释放,则必须手动释放它们。但是,如果您使用的API只适用于原始类型,那么您不必发布任何内容。

如果你没有使用上面的任何东西,那么你很有可能不需要准备好直接释放任何非托管的类。

有一些类型使用本机资源--你可能已经遇到过了--它们是幕后的托管包装器。他们通过编组在其Dispose实现中释放这些资源。

例如,FileStream托管类持有给定文件的非托管句柄。FileStream本身是由GC跟踪和收集的托管类,但非托管句柄不是,必须手动释放它,因此,如果您( FileStream的用户)没有在代码中调用它的Dispose方法,则该句柄将保留在内存泄漏中,直到应用程序退出。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52974602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档