http://msdn.microsoft.com/zh-cn/library/system.gc.keepalive.aspx

http://www.cnblogs.com/ren700622/archive/2010/08/03/1791232.html

根据官方的说法,GC的垃圾回收是酱子地:

  • 垃圾回收器搜索托管代码中引用的托管对象。

  • 垃圾回收器尝试完成没有被引用的对象。

  • 垃圾回收器释放没有被引用的对象并回收它们的内存。

也就是说在.NET中GC是不定时的进行以上的三项工作,对在托管对象中没有任何引用的对象进行回收,当然何时运行垃圾回收是.NET说了算,也可以使用代码强制其运行回收例程,但据官方讲似乎不赞成这种做法(貌似ms除了他建议的办法,其它办法都不赞成的),说是会影响性能.

好吧就按官方说的办,但是问题出来了,请看下面代码:


 1 public class Paramet_A
2 {
3 private byte[] p_V;
4
5 public byte[] VV
6 {
7 get{return p_V;}
8 set{p_V=value;}
9 }
10 }
11 public class NativeInvoke
12 {
13
14 [DllImport("winmm.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
15 public static extern NativeMedhod(byte* x);
16
17 public void InvokeNativeMethod()
18 {
19 Paramet_A a=new Paramet_A();
byte* x=(byte*)a.VV;
20 NativeMedhod(x);
21 }
22 }

在上面代码中申明了两个类:Paramet_A和 NativeInvoke

Paramet_A类是作为一个参数指针传给NativeInvoke.NativeMethod的,而NativeInvoke.NativeMethod

是假定本机存在的一个调用方法,上面代码的方法InvokeNativeMethod看起来好象没有错误,确实如此,在单线程运行中或者是在GC没有运行垃圾回收时它能很好的工作,但是当语句运行到20行但没有返回时该死的GC运行了,那问题就出来了,GC发现变量a没有引用了就做了它了,而其实在非托管代码中它还要使用,这样在非托管代码中肯定出现无法预料的结果了(好象ms特喜欢这种说法,无法预料,嗨嗨,这里套用下),解决办法就是在20行后添加一行GC.KeepAlive(a),据说这样是为了防止GC来回收它,也就是说对a进行引用一下,避免20行代码没有返回时a变量被回收,哈哈这下明白了.

再请看一段代码:


 1 public Class ThreadInvoke
2 {
3
4 private void ThreadStart_T()
5 {
6 Paramet_A a=new Paramet_A();
7 byte[] x=a.BB
8 //下面就是做点啥的代码
9 //.......
10 if(x[0]==1)//这行代码会出问题?
11 {
12 }
13 }
14
15 public void Run()
16 {
17 Thread th=new Thread(new ThreadStart(ThreadStart_T));
th.Start();
18 }
19 }

好了,你看Run方法,它开始了一个线程,该线程的执行体是ThreadStart_T方法,这个方法也看似没啥问题,但是假定运行到第十行的时侯GC又开始运行了,那就又是一个无法预料了,因为a被终结了,解决的办法就是在12行后加一句GC.KeepAlive(a).

说到这里有人要说了,那GC.KeepAlive这个方法不是有好多地方要用到吗?是的,从线程安全角度讲,任何局部变量都最好在它结束使命前用一下GC.KeepAlive,不过这好象也太........,幸运的是ms又说了:KeepAlive 方法除了延长作为参数传递的对象的生存期之外,不会执行任何操作,也会不产生任何其他副作用,哈哈所以说尽管用吧.

哦对了,补充一句,用在引用对象上,并且预料到该引用对象有成员被其它代码所使用.

GC垃圾回收之GC.KeepAlive方法的更多相关文章

  1. 乐字节Java|GC垃圾回收机制、package和import

    本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...

  2. 垃圾回收机制GC知识再总结兼谈如何用好GC

    一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般 ...

  3. C#垃圾回收机制(GC)

    GC的前世与今生 虽然本文是以.net作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年,由鼎鼎大名的图林奖得主John McCarthy所实现的Lisp语言就已经提供了GC的功能,这是 ...

  4. 数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>

    C# 基础接口篇 一.多态复习 使用个new来实现,使用virtual与override    -->new隐藏父类方法 根据当前类型,电泳对应的方法(成员)    -->override ...

  5. 垃圾回收机制GC知识再总结兼谈如何用好GC(转)

    作者:Jeff Wong 出处:http://jeffwongishandsome.cnblogs.com/ 本文版权归作者和博客园共有,欢迎围观转载.转载时请您务必在文章明显位置给出原文链接,谢谢您 ...

  6. GC垃圾回收算法

    什么是GC垃圾回收呢.日常生活中我们去餐厅吃饭吃完饭,吃完饭走了餐具不用管,服务员在把餐具拿走,这是一种方式,服务员怎么知道他要来把餐具拿走呢,因为你走了,这个位置空了.服务员什么时候拿走餐具很重要, ...

  7. GC垃圾回收

    我们在开发需求的时候,可能很少关注到垃圾回收,因为我们绝大多数的时候都是使用的托管资源,托管资源的内存回收.net已经帮我们做了,但是.net的内存回收不是实时的,所以我们还是要关注下.net的垃圾回 ...

  8. JVM学习02:GC垃圾回收和内存分配

    JVM学习02:GC垃圾回收和内存分配 写在前面:本系列分享主要参考资料是  周志明老师的<深入理解Java虚拟机>第二版. GC垃圾回收和内存分配知识要点Xmind梳理 案例分析1-(G ...

  9. JVM总括二-垃圾回收:GC Roots、回收算法、回收器

    JVM总括二-垃圾回收:GC Roots.回收算法.回收器 目录:JVM总括:目录 一.判断对象是否存活 为了判断对象是否存活引入GC Roots,如果一个对象与GC Roots没有直接或间接的引用关 ...

随机推荐

  1. php后台如何避免用户直接进入方法实例

    这篇文章介绍了php后台如何避免用户直接进入方法实例,有需要的朋友可以参考一下 1)创建BaseController控制器继承Controller(后台的一切操作要继承BaseController): ...

  2. fis3简单教程

    #进入工作目录初始化fis3目录(此步非必须,如果当前目录已有fis-conf.js文件,可以不用初始化)fis3 init#部署(<path>为部署目录,如果想部署到当前output目录 ...

  3. 1096. Consecutive Factors (20)

    Among all the factors of a positive integer N, there may exist several consecutive numbers. For exam ...

  4. hadoop的核心思想

    hadoop的核心思想 1.1.1. hadoop的核心思想 Hadoop包括两大核心,分布式存储系统和分布式计算系统. 1.1.1.1. 分布式存储 为什么数据需要存储在分布式的系统中哪,难道单一的 ...

  5. 保持iOS上键盘出现时输入框不被覆盖

    如果屏幕中的内容项目比较多,键盘就可能覆盖住文本输入框之类的对象.你必须调整你的内容,使得输入框保持可见. 你会想到哪些处理方法呢? 第一种, 临时调整窗口中各个视图的大小,使得键盘从下向上占领的区域 ...

  6. 从零开始学ios开发(八):Autorotation and Autosizing

    不好意思,这一篇间隔的时间有点长,最近实在是事情太多,耽搁了,好了,长话短说,下面继续学习ios. 这次学习的内容是Autorotation和Autosizing,Autorotation就是屏幕内容 ...

  7. Yii2 composer更新后报错: Calling unknown method: yii\web\UrlManager::addRules()

    网上搜了好多答案,基本上都是让你在composer.json里面添加这样一段话: "extra": { "asset-installer-paths": { & ...

  8. (转) linux目录结构详细介绍

    转自:http://yangrong.blog.51cto.com/6945369/1288072 目录 1.树状目录结构图 2./目录 3./etc/目录 4./usr/目录 5./var/目录 6 ...

  9. php文字水印和php图片水印实现代码(二种加水印方法)

    文字水印 文字水印就是在图片上加上文字,主要使用gd库的imagefttext方法,并且需要字体文件.效果图如下: $dst_path = 'dst.jpg';//创建图片的实例$dst = imag ...

  10. 如何自定义Liferay 7 portal的Log in登录界面

    前提: 1. Liferay portal 7 2. Liferay IDE 3.0.1 Liferay现有的工具中提供了很多修改portal的模板,以满足开发者的各种自定义需求. 修改的原理是利用M ...