C# CLR via 对象内存中堆的存储【类型对象指针、同步块索引】
最近在看书,看到了对象在内存中的存储方式。
讲到了对象存储在内存堆中,分配的空间除了类型对象的成员所需的内存量,还有额外的成员(类型对象指针、 同步块索引 ),看到这个我就有点不懂了,不知道类型对象指针是什么,指向的什么?
从网上找也没有找到,最后往下看,书中有些描述。说下我的理解:
类型对象指针:指向类型对象存储的地址,假如有一个类型Person,它在堆中有一块区域存储它内部的字段和成员以及两个额外成员(类型对象指针、 同步块索引 ),类型对象的类型对象指针指向的是System.Type的地址。
因为Person类型在内存中相对于System.Type也是作为一个对象存在的,System.Type类型也是一个类型对象,它的类型对象指针指向本身;
实例化一个Person对象,Person p = new Person(); p对象在内存堆中也分配一块区域存储它内部的字段和成员以及两个额外成员(类型对象指针、 同步块索引 ),p的类型对象指针指向Person类型在堆中的地址。
同步块索引:先说一下同步块,.NET团队在设计基本框架时充分考虑了线程同步的问题,其结果就是.NET为每一个堆内对象都提供了支持线程同步的功能,这就是同步机制的雏形【参考:http://genwoxuedotnet.blog.51cto.com/1852748/504107】
但是对每个堆内对象都分配同步块有一个较大的弊端,就是这样增大了内存的消耗。在一般的系统中,需要同步机制支持的对象可能只占少数,这样对于大多数对象来说,一个同步块的内存消耗就完全被浪费了。鉴于这一点,.NET框架采用了一种折中的办法,就是实际只为每个堆内对象分配一个同步索引,该索引中只保存一个表明数组内索引的整数。.NET在加载时会新建一个同步块数组,当某个对象需要被同步时,.NET会为其分配一个同步块,并且把该同步块在同步块数组中的索引加入该对象的同步块索引中。
同步块机制包含如下的几点:
· 在.NET被加载时初始化同步块数组。
· 每一个被分配在堆上的对象都会包含两个额外的字段,其中一个存储类型指针,而另外一个就是同步块索引,初始时被赋值为-1。
· 当一个线程试图使用该对象进入同步时,会检查该对象的同步索引。如果索引为负数,则会在同步块数组中寻找或者新建一个同步块,并且把同步块的索引值写入该对象的同步索引中。如果该对象的同步索引不为负值,则找到该对象的同步块并且检查是否有其他线程在使用该同步块,如果有则进入等待状态,如果没有则申明使用该同步块。
同步块是指.NET维护的同步块数组中的某个元素
C# CLR via 对象内存中堆的存储【类型对象指针、同步块索引】的更多相关文章
- 危险代码:如何使用Unsafe操作内存中的Java类和对象
危险代码:如何使用Unsafe操作内存中的Java类和对象—Part1 危险代码:如何使用Unsafe操作内存中的Java类和对象—Part2 危险代码:如何使用Unsafe操作内存中的Java类和对 ...
- 揭示同步块索引(中):如何获得对象的HashCode
转自:http://www.cnblogs.com/yuyijq/archive/2009/08/13/1545617.html 题外话:为了尝鲜,也兴冲冲的安装了Win7,不过兴奋之余却郁闷不已,由 ...
- JavaScript中的变量在内存中的具体存储形式
栈内存和堆内存 JavaScript中的变量分为基本类型和引用类型 基本类型是保存在栈内存中的简单数据段,它们的值都有固定的大小,保存在栈空间,通过按值访问 引用类型是保存在堆内存中的对象,值大小不固 ...
- C语言中float,double类型,在内存中的结构(存储方式)
C语言中float,double类型,在内存中的结构(存储方式)从存储结构和算法上来讲,double和float是一样的,不一样的地方仅仅是float是32位的,double是64位的,所以doubl ...
- @清晰掉 C++ 中的 enum 结构在内存中是怎么存储的?
C++ 中的 enum 结构在内存中是怎么存储的? C++ C++ 中的 enum 结构在内存中是怎么存储的?里面存储的是常量值吗? 关于占用内存的大小,enum类型本身是不占内存的,编译器直接 ...
- [C#学习笔记]类型对象指针和同步块索引
写在前面 看<CLR via C#>第四章时,看到了类型对象指针和同步块索引这两个概念,不知如何解释,查看过相关资料之后,在此记录. 类型对象指针 <CLR via C#>中的 ...
- 在C中判断变量存储类型(字符常量/数组/动态变量)
在C中判断变量存储类型(字符常量/数组/动态变量) 在chinaunix论坛上有人问到关于变量存府类型的问题,我觉得可以写个测试代码加深大家对内存使用和布局的理解.下面我把原问题及处理办法贴出来,限供 ...
- 日历类和日期类转换 并发修改异常 泛型的好处 *各种排序 成员和局部变量 接口和抽象类 多态 new对象内存中的变化
day07 ==和equals的区别? ==用于比较两个数值 或者地址值是否相同. equals 用于比较两个对象的内容是否相同 String,StringBuffer.StringBuilde ...
- 【Java】运行时Java对象在内存中是如何存储的?
翻译自这一篇文章 我们知道函数在内存中实现为一个活动记录的栈.我们也知道Java方法在JVM栈区中实现为一个帧栈而Java对象是在堆区进行分配的. Java对象在堆内存中是怎样的呢?一旦对象保存在内存 ...
随机推荐
- socket的阻塞与非阻塞,同步与非同步
网络编程中通常提到四种方式,同步/异步,阻塞/非阻塞.以下对它们的概念进行总结 1.同步/异步:主要针对C端 同步:所谓同步,就是在C端发出一个功能调用时,在没有得到结果之前,调用不返回,也就是必须一 ...
- FPGA中带优先级的if else if与不带优先级的case的探讨
我们知道在书本上都说让我们尽量使用不带优先级的的数据选择器,今天我们就来探讨一下二者的区别. 例子1:带优先级的的数据选择器,综合成功,且没有任何警告. module detection_prio # ...
- SSAS 后端数据库访问模块中存在错误。 为绑定指定的大小太小,导致一个或多个列值被截断。
在处理AS的过程中报错如上,经排查发现原因为数据库 “工号” 字段长度过长导致. 因为我的字段内容基本是人名加工号:张三/1001 不曾想有用户录入非正常数据 :张三/100/1001 这样导致我截取 ...
- [转]OpenContrail 体系架构文档
OpenContrail 体系架构文档 英文原文:http://opencontrail.org/opencontrail-architecture-documentation/ 翻译者:@KkBLu ...
- 手把手教你读取Android版微信和手Q的聊天记录(仅作技术研究学习)
1.引言 特别说明:本文内容仅用于即时通讯技术研究和学习之用,请勿用于非法用途.如本文内容有不妥之处,请联系JackJiang进行处理! 我司有关部门为了获取黑产群的动态,有同事潜伏在大量的黑产群 ...
- Docker学习笔记-简单运行.netcore
前言: 环境:centos7.5 64 位 正文: 拉取 microsoft/dotnet, 安装完毕后执行 docker images 可以看到本地已经包含 microsoft/dotnet #包含 ...
- HTTP 协议常见的状态码
HTTP状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 状态码的类别: 记录在RFC2616上的HTTP状态码有40种,再加上WebDAV等的扩展,数量 ...
- LabVIEW(七):多态VI
1.多态VI概念:可以处理多种不同数据类型的VI被称为“多态VI”.多态VI根据输入或输出的 数据类型,再选择调用一个针对这种数据类型实现功能的VI,这些针对某种数据类型实现功能的VI称作“实例VI” ...
- Spark基础-scala学习(七、类型参数)
类型参数是什么 类似于java泛型,泛型类 泛型函数 上边界Bounds 下边界 View Bounds Context Bounds Manifest Context Bounds 协变和逆变 Ex ...
- 神经网络架构PYTORCH-宏观分析
基本概念和功能: PyTorch是一个能够提供两种高级功能的python开发包,这两种高级功能分别是: 使用GPU做加速的矢量计算 具有自动重放功能的深度神经网络从细的粒度来分,PyTorch是一个包 ...