C# fixed详解
相信很多人在这样或那样的项目中,或者无意间看到了fixed语句块,看到之后你肯定会疑问:
1、这个fixed关键字是做什么用的?
2、什么情况下需要该关键字?
3、这个关键字该怎么用?
我相信解决了上面四个问题之后,你对这个fixed语句就理解和掌握到位了,我也在网上大致浏览了下,网上关于该关键字的详细说明太少太少了,基本都是摘抄MSDN官方文档,毫无自身理解与发散出来的东西,当然完全依据MSDN的只言片文也能理解不过相当费劲,在这里我结合自己的理解给大家说明下该关键字的用法,希望各位看过之后能给出自己的想法。
在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详解的更多相关文章
- 【转】CSS中position属性( absolute | relative | static | fixed )详解
我们先来看看CSS3 Api中对position属性的相关定义: static:无特殊定位,对象遵循正常文档流.top,right,bottom,left等属性不会被应用. relative:对象遵循 ...
- CSS中position属性( absolute | relative | static | fixed )详解
我们先来看看CSS3 Api中对position属性的相关定义: static:无特殊定位,对象遵循正常文档流.top,right,bottom,left等属性不会被应用. relative:对象遵循 ...
- css position: relative | absolute | static | fixed详解
static(静态):没有特别的设定,遵循基本的定位规定,不能通过z-index进行层次分级. fixed(固定定位):这里所固定的参照对象是可视窗口而并非是body或是父级元素.可通过z-index ...
- css样式之background详解
background用法详解: 1.background-color 属性设置元素的背景颜色 可能的值 color_name 规定颜色值为颜色名称的背景颜色(比如 red) he ...
- [转]keil使用详解
第一节 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上.结构性.可读性.可维护性上有明显的优势,因而易学易用.用过 ...
- css样式之background详解(格子效果)
background用法详解: 1.background-color 属性设置元素的背景颜色 可能的值 color_name 规定颜色值为颜色名称的背景颜色(比如 red) he ...
- linux管道命令grep命令参数及用法详解---附使用案例|grep
功能说明:查找文件里符合条件的字符串. 语 法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...
- jqGrid APi 详解
jqGrid APi 详解 jqGrid皮肤 从3.5版本开始,jqGrid完全支持jquery UI的theme.我们可以从http://jqueryui.com/themeroller/下载我们所 ...
- CSS详解
Web前端开发css基础样式总结 颜色和单位的使用 颜色 用颜色的名字表示颜色,比如:red 用16进制表示演示 比如:#FF0000 用rgb数值表示颜色,rgb(红,绿,蓝),每个值都在0-255 ...
随机推荐
- 用10张图来看机器学习Machine learning in 10 pictures
I find myself coming back to the same few pictures when explaining basic machine learning concepts. ...
- 程序编译是出现"field has incomplete type"问题的解决
在编译程序是出现了如下错误, 类或结构体的前向声明只能用来定义指针对象或引用,因为编译到这里时还没有发现定义,不知道该类或者结构的内部成员,没有办法具体的构造一个对象,所以会报错. 将类成员改成指针就 ...
- CSS_LESS 语法/函数详解
嵌套规则 01 #header { color: black; }#header .navigation { font-size: 12px; 02 }#header .logo { 03 w ...
- C++数组参数应用方式探讨(转)
对于经验丰富的编程人员来说,C++编程语言应该是他们经常使用于程序开发的一种实用性语言.那么,在C++中,C++数组参数永远不会按值传递.它是传递第一个元素(准确地说是第0个)的指针. 例如,如下声明 ...
- myBatis + SpringMVC上传、下载文件
摘自: http://limingnihao.iteye.com/blog/1069503 环境:maven+SpringMVC + Spring + MyBatis + MySql 本文主要说明如何 ...
- CentOS7下命令安装火狐浏览器
使用命令安装火狐浏览器,需要切换root(su root)下,执行下面的命令,自动下载所需依赖包,完成安装 yum -y install firefox 然后重启即可
- Node Server零基础——开发环境文件自动重载
收录待用,修改转载已取得腾讯云授权 前言 在 web 前端开发中,我们会借助 Grunt.Gulp 和 Webpack 等工具的 Watch 模块去监听文件变化,那服务端应该怎么做?其实文件变化的监听 ...
- C# 怎么显示中文格式的星期几
1.DateTime.Now.ToString("dddd",new System.Globalization.CultureInfo("zh-cn")); 2 ...
- MongoDB 基础命令 (MongoDB Shell)
1.我们 mongodb 安装成功后,用上一篇的方法启动 mongodb服务 然后使用 mongodb shell 来做数据库的增删改查 2.创建数据库 语法: use 数据库名称 案例: > ...
- UNIX网络编程读书笔记:shutdown函数
终止网络连接的通常方法是调用close函数.不过close有两个限制,却可以使用shutdown来避免. close 把描述字的引用计数减1,仅在该计数变为0时才关闭套接口.使用shutdown可以不 ...