c#中的非托管资源,是在内存中的哪里开辟的?

葬爱の丫 2014-01-08 10:31:36
神们,C#内存分为线程的堆栈和托管堆。而这非托管资源又开辟于哪里?不可能是栈或托管堆上啊。
还有一个windows菜鸟问题:对某位图进行操作,需要先获取位图句柄。请问这个获取句柄的操作,是在内存中开辟一块空间来存储这个位图?然后返回地址?如果没有获取句柄的操作,则程序的资源位图只存在于电脑硬盘中,没有存储在内存中? 我把这个句柄获得到后,别的程序也可以通过这个句柄来操作位图么?
...全文
366 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
葬爱の丫 2014-01-11
  • 打赏
  • 举报
回复
引用 11 楼 qldsrx 的回复:
调用dispose是用来释放非托管资源的,如果不存在非托管资源,那步完全可以省略,即使执行了也没有任何动作。而你不清楚是否有非托管资源的话,最好是调用下,做到及时释放内部资源,而对象本身何时释放就不知道了,看GC的高兴,但必须是没有任何引用的情况下。
谢谢!
qldsrx 2014-01-10
  • 打赏
  • 举报
回复
调用dispose是用来释放非托管资源的,如果不存在非托管资源,那步完全可以省略,即使执行了也没有任何动作。而你不清楚是否有非托管资源的话,最好是调用下,做到及时释放内部资源,而对象本身何时释放就不知道了,看GC的高兴,但必须是没有任何引用的情况下。
葬爱の丫 2014-01-10
  • 打赏
  • 举报
回复
引用 8 楼 findcaiyzh 的回复:
释放托管对象,一般值空就可以吧。
谢谢你的回答,但我还有上述疑问......
葬爱の丫 2014-01-10
  • 打赏
  • 举报
回复
一旦一个引用类型出了其作用域,就相当于值空了啊,堆中对象没有了引用指向它,等待GC回收就行了。那我何必还要在引用类型出作用域之前,调用dispose(true)来显示写一下:“引用类型为空”呢?不是多此一举么?这就叫所谓“释放托管资源”的操作??
宝_爸 2014-01-10
  • 打赏
  • 举报
回复
释放托管对象,一般值空就可以吧。
threenewbee 2014-01-09
  • 打赏
  • 举报
回复
另外,从一个更高的层次说这个问题,虽然可能现在对你来说还有些深。 当你成为一个合格的职业程序员的时候,你应该懂得“防御性编程”这个最基本的观点。你的代码和外部的代码交互的时候,你应该对外部代码有最低的预期。比如说,当你调用一个第三方的类,你不能假设它的编写者一定在析构函数(你所谓的终结器)调用了dispose,也许那个代码出自一个菜鸟之手。那么无论如何,显式地调用dispose可以确保这写资源被释放。再比如,你应该明白,编写更有效率的代码,对外部资源占用最小的代码,是一个程序员的美德。好比一个汽车司机,把汽车开得忽快忽慢,颠三倒四,也能把乘客送到目的地。一个蛋糕店,将蛋糕的花纹做的粗糙一些,反正蛋糕最后都是吃的,似乎也不打紧。但是作为一种职业,你就应该把事情给做好。而不是能用就行。所以往往业余程序爱好者总是问,什么代码是不必要的,他们通过“尝试”发现似乎自己丢三落四也问题不大。那他们应该感谢真正的代码是那些职业的程序员创建的,所有的人不和他们一样都是乌合之众。
threenewbee 2014-01-09
  • 打赏
  • 举报
回复
这种问题很容易想明白。 那些在内存耗尽前首先会被耗尽的资源就不能等到释放内存的时候再释放。 比如说,如果你的数据库只允许10个并发连接。但是开了100个连接对象只占用很少的内存并不足以让GC开始回收。那么你当然要手工释放。 再比如,你读写完文件,自然希望尽快取消文件的锁定,那么你也不应该等析构函数调用dispose的时候再调用。
葬爱の丫 2014-01-09
  • 打赏
  • 举报
回复
感谢各位的指导,这几天我一直在查:如果分辨哪些是非托管资源...需要程序员手动释放资源。本来看到很多人说数据库连接、字节流等是非托管资源,我认为我已经明白些了...但是后来看到一个文章:SQLConnection,FileStream是托管类!这些类中有非托管资源,这些类已由系统实现了终结器和dispose,所以如果我们不显示调用其close方法,这些类在GC回收时,也会在终结器中进行释放非托管资源的操作。 我认为这是对的,系统写好的类一定已写好这些释放资源的代码,只是如果我们显示去释放,会使内存回收的更及时些,我们不写的话,最终这些类重写的终结器也会释放非托管资源,只是性能下降而已。 那么我们何时才“必须要”手动编写释放非托管资源的代码??能不能给举个例子??
葬爱の丫 2014-01-09
  • 打赏
  • 举报
回复
谢谢大侠!最后一个问题:MSDN上建议编写dispose(bool),bool传true时,将托管和非托管资源一并释放。托管堆是由GC释放的,我无权进行内存释放操作。请问那在这里,,,又何谈释放托管资源呢...?我无权回收啊.GC标记没有引用指向托管资源了,由它回收啊。
sinodzh 2014-01-09
  • 打赏
  • 举报
回复
堆栈。 可以看下clr var c# 看下里面讲解值类型和引用类型的段落。
threenewbee 2014-01-08
  • 打赏
  • 举报
回复
很简单,非托管堆呗。 获取句柄的操作,是在内存中开辟一块空间来存储这个位图? 显然是先“开辟空间”(得到一个DC)然后才有地址。

110,568

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧