相信很多人在这样或那样的项目中,或者无意间看到了fixed语句块,看到之后你肯定会疑问:

1,这个fixed关键字是做什么用的?

2,什么情况下需要该关键字?

3,这个关键字该怎么用?

我相信解决了上面四个问题之后,你对这个fixed语句就理解和掌握到位了,我也在网上大致浏览了下,网上关于该关键字的详细说明太少太少了,基本都是摘抄MSDN官方文档,毫无自身理解与发散出来的东西,当然完全依据MSDN的只言片文也能理解不过相当费劲,在这里我结合自己的理解给大家说明下该关键字的用法,希望各位看过之后能给出自己的想法。

本文地址:http://hi.baidu.com/jiang_yy_jiang/blog/item/de22fcd15d017f269a502770.html

在MSDN如下介绍:

1、fixed 语句禁止垃圾回收器重定位可移动的变量。fixed 语句只能出现在不安全的上下文中。Fixed 还可用于创建固定大小的缓冲区。
2、fixed 语句设置指向托管变量的指针并在 statement 执行期间“钉住”该变量。如果没有 fixed 语句,则指向可移动托管变量的指针的作用很小,因为垃圾回收可能不可预知地重定位变量。C# 编译器只允许在 fixed 语句中分配指向托管变量的指针。
3、执行完语句中的代码后,任何固定变量都被解除固定并受垃圾回收的制约。因此,不要指向 fixed 语句之外的那些变量。

看到这几乎话你可能云里雾里,雾里云里,

第一句:fixed禁止垃圾回收器定位可移动变量这到底是怎么一回事?

如果你不理解这句话说明你得需要去了解下GC,我们知道GC是CLR管理下的垃圾回收器。当进程初始化时,CLR保留一块连续的地址空间,这个地址空间最初并没有对应的物理存储空间,这个地址空间就是托管堆。在托管堆中,连续分配的对象可以确保他们在内存中时连续的。托管堆维护着一个叫做NextObjPtr的指针,它指向下一个对象在堆中的分配位置。调用new操作符创建对象时,如果没有足够的地址空间来分配对象,也即对象的字节数+NextObjPtr指针的地址超过了地址空间末尾则需要进行一次垃圾回收。

回收机制是采用根标记堆上的对象,当根不可达时则回收堆所占的内存(这里不去扩展,只给个大概的脉络,其实还涉及GC的代Generation),当回收完毕时的下一阶段就是压缩内存,这个阶段垃圾回收器线性的便利堆,以寻找未标记(垃圾)对象的连续内存块,如果发现的内存块比较小,垃圾回收期会忽略它们,但是,如果发现大的,可用的连续内存块,垃圾回收器会把非垃圾的对象移动到这里以压缩堆。

很自然地,移动内存中的对象之后,包含“指向这些对象的指针”的变量和CPU寄存器现在都会变得无效。所以垃圾回收器必须重新访问应用程序的所有根,并修改它们来指向对象的新内存位置。另外,如果对象中的字段指向的是另一个已移动了位置的对象,垃圾回收器要负责更正这些字段。堆内存压缩之后,托管堆的NextObjPtr指针指向紧接在最后一个非垃圾对象之后的对象之后的位置。

   到这里......哇 看了这么久你肯定累了,可以休息下哈.................................................................................................

上面所说的都是在托管环境的CLR指导下完成的,那如果是非安全代码如果是指针呢?指针指向了一个托管对象,而GC时内存会压缩,谁还管你的非安全指针,我们CLR只负责托管代码啊!所以微软给出的解决办法是采用fixed关键字。

   所以当你看完到这里而且明白的话第1,2个问题都解决啦!!

   对于第三个问题,我采用一个实例结合MSDN说明:

结合上面的理论,如果还能输出结果说明指针操作成功,没有因为GC的回收造成指针操纵了不正确的地址,因为fixed语句块钉住了ints变量,禁止垃圾回收器操作内存地址,重定位可移动变量。为什么要这样做呢?我们不是可以用托管代码直接操作数组吗?

没错,但你别忘了指针操作数组是很快的,因为它会关闭数组索引的检查即关闭索引的上下限检查,这样的好处是:你的程序是性能优先,以性能为核心的时候这反而是最佳的解决方案!

C# fixed语句固定变量详解的更多相关文章

  1. [转]mysqldump备份还原和mysqldump导入导出语句大全详解

    FROM : http://www.cnblogs.com/zeroone/archive/2010/05/11/1732834.html mysqldump备份还原和mysqldump导入导出语句大 ...

  2. shell 脚本之判断语句 if 详解

    使用 Linux 系统这么长时间,对 shell 脚本也算是比较熟悉.其实不管是搞开发,还是搞运维,shell 脚本都是必备的基本技能.这次抽时间好好总结一下 shell 方面的知识,综合的再学习一下 ...

  3. MySQL查询语句(select)详解(2)

    7.子查询 当进行查询的时候,需要的条件是另外一个select语句的结果,这时候就要用到子查询 用于子查询的主要关键字有:in,not in,=,!=,exists,not exists等. 以下两张 ...

  4. static{ }语句块详解

    static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法.举ge例子: public class Test { public static i ...

  5. 转 java中static{}语句块详解

    原文地址:http://blog.csdn.net/lubiaopan/article/details/4802430     感谢原作者! static{}(即static块),会在类被加载的时候执 ...

  6. java中static{}语句块详解

    static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,下面我们详细的讨论一下该语句块的特性及应用. 一.在程序的一次执行过程中,stati ...

  7. hive操作语句使用详解

    #创建表人信息表  person(String name,int age) hive> create table person(name STRING,age INT)ROW FORMAT DE ...

  8. SQL语句函数详解__sql聚合函数

    函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类:单行函数.组函数 本文将讨论如何使用单行函数及 ...

  9. JavaScript 循环语句入门详解

    JavaScript Switch 语句 语法 switch(n) { case 1: 执行代码块 1 break; case 2: 执行代码块 2 break; default: n 与 case ...

随机推荐

  1. 安卓APP载入HTML5页面解决方式总结

    因为H5页面在移动端的兼容性及扩展性方面体现出来的优势,又兼得APP中植入H5页面相应用的灵活性有大大的提升(如活动.游戏的更新等).APP开发不可避免的须要载入一些H5页面.但安卓client对网页 ...

  2. 单片机: EEPROM和串口通信

    名称:IIC协议 EEPROM24c02 通过串口通信存数读取数据 内容:此程序用于检測EEPROM性能,測试方法例如以下:写入24c02一个数据,然后在内存中改变这些数据. 掉电后主内存将失去这些信 ...

  3. 【LeetCode-面试算法经典-Java实现】【168-Excel Sheet Column Title(Excell列标题)】

    [168-Excel Sheet Column Title(Excell列标题)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a positive in ...

  4. [jzoj NOIP2018模拟11.02]

    嗯T1忘记取模了,100到20 嗯T2忘记了那啥定理,暴力也写炸了,这题我认 嗯T3线段树合并分裂没有写炸,考场上就知道妥妥的70分.但是,分数出的时候听到有人说暴力也是70分,我???脸黑,枉我敲了 ...

  5. Android 对话框黑色边框的解决

    代码解决 : Dialog dialog = new Dialog(this); Window win = dialog.getWindow(); win.setBackgroundDrawableR ...

  6. 001.ActiveMQ概述

    1. 概念 ActiveMQ是Apache推出的,一款开源的,完全支持JMS1.1和J2EE1.4规范的JMS Provider实现的消息中间件(Message Oriented Middleware ...

  7. ASP调用WebService转化成JSON数据,附json.min.asp

    首先定义SOAP数据,然后创建HTTP对象,然后使用POST提交,获取状态码为200,就说明调用成功,再进行下一步操作…… <!--#Include virtual="/Include ...

  8. 路飞学城Python-Day13

    [2.常用模块-模块的种类和导入方法] 1.什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长.越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分 ...

  9. 小程序QQ版表情解析组件

    代码片段: [https://developers.weixin.qq.com/s/KLaD5MmD7V45) GitHub: https://github.com/WozHuang/Miniprog ...

  10. 查看centos7启动项

    [root@k8s-master ~]# chkconfig Note: This output shows SysV services only and does not include nativ ...