.NET对象的内存布局
每个虚拟机都有它自己的对象布局,本文我们将针对sscli源码和windbg调试器来查看不同类型的.net对象布局。
在.net虚拟机里,每个对象都需要保存这些信息:
- 对象的类型;
- 对象实例的成员属性(field)值;
- hash值、锁信息等其他数据结构。
普通对象
在CLR里,对象在托管代码(managed code)和非托管代码(unmanaged code)里有不同的表现形式。在托管代码里,所有对象的基类Object类型是在 clr\src\bcl\system\Object.cs里定义,而其在非托管世界里,则复杂的多,由在clr\src\vm\object.h里定义的Object类型,clr\src\vm\SyncBlk.h里定义的ObjHeader等类型实现。对象在非托管代码理的内存物理布局如下图所示:
- 在非托管代码里,对象实际上有两个指针。
- object指针就是虚拟机返回给托管代码的对象引用地址,从这个指针开始,托管代码就可以获取到任何一个对象的类型以及成员变量信息。
- 而另外一个指针objhead,实际上是非托管代码里,每个.NET对象实际的指针,在这个指针后面,包含了控制线程同步,甚至是COM Interop相关信息的SyncBlock索引,这个索引的作用我们会在后文提到。因为索引只用到32位字节,所以在64位系统运行的时候,会加上一个填充用的DWORD以便补齐内存边界。
- object指针后面紧跟的就是该对象所属的类型:MethodTable,MethodTable顾名思义就是函数表,在.NET里它就是对象类型的代表,在后文我们也会详细说明它。
- 类型信息后面就是每个对象实例成员变量的值信息了,如果是成员变量是引用类型,那么就保存被引用的对象的object指针(不是objhead),如果是值类型,比如说结构体,那么就按照值类型的内存布局,将变量值直接保存在对象的内存区域里。

虽然.NET里所有引用类型的对象都从Object类型里继承,一些特殊的对象,在CLR里也在非托管代码里定义了一份不同的布局,方便虚拟机的处理。
数组对象 - Array
在托管代码里,其在 clr\src\bcl\system\Array.cs 里定义,在非托管代码里,其在 clr\src\vm\object.h 里定义。之所以这样做,是因为数组对象即可以保存引用类型,也可以保存值类型,而且为了方便程序访问数组的长度,数组对象实际上是将长度信息直接保存在内存里了,如下图是其内存布局:
- 除了将长度信息直接保存到内存以外,如果是多维数组,则还会将各个纬度的上标和下标信息都保存到内存里,这主要是支持向VB这样的可以修改数组上下标的编程语言设计的。
- 如果是引用类型,则会把成员元素的类型指针保存在数组里;
- 如果是值类型,则直接保存成员元素的内容。

字符串对象
在托管代码里,其在 clr\src\bcl\system\String.cs 里定义,在非托管代码里,其在 clr\src\vm\object.h 里定义。
- 因为在.NET里字符串是不能修改的,可以将其当作数组处理,所以.NET直接将字符串的长度保存在内存里;
- 为了方便非托管代码处理字符串,每个字符串最后以 NULL 结尾,当然字符类型是WCHAR,而不是CHAR,这也就是说.NET下面字符默认是UNICODE。

.NET对象的内存布局的更多相关文章
- VS中C++对象的内存布局
本文主要简述一下在Visual Studio中C++对象的内存布局,这里没有什么测试代码,只是以图文的形式来描述一下内存分布,关于测试的代码以及C++对象模型的其他内容大家可以参考一下陈皓先生的几篇博 ...
- C++ 对象的内存布局(上)
C++ 对象的内存布局(上) 陈皓 http://blog.csdn.net/haoel 点击这里查看下篇>>> 前言 07年12月,我写了一篇<C++虚函数表解析>的文 ...
- JVM——深入分析对象的内存布局
概述 一个对象本身的内在结构需要一种描述方式,这个描述信息是以字节码的方法存储在方法区中的.Class本身就是一个对象,都以KB为单位,如果new Integer()为了表示一个数据就占用KB级别的内 ...
- Java对象的内存布局
对象的内存布局 平时用java编写程序,你了解java对象的内存布局么? 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域: 对象头 实例数据 对齐填充 对象头 对象头包括两部分信息: ...
- jvm学习记录-对象的创建、对象的内存布局、对象的访问定位
简述 今天继续写<深入理解java虚拟机>的对象创建的理解.这次和上次隔的时间有些长,是因为有些东西确实不好理解,就查阅各种资料,然后弄明白了才来做记录. (此文中所阐述的内容都是以Hot ...
- Java对象的内存布局以及对象所需内存大小计算详解
1. 内存布局 在HotSpot虚拟机中,对象的内存布局可以分为三部分:对象头(Header). 实例数据(Instance Data)和对齐填充(Padding). 1) 对象头(Header): ...
- C++ 对象的内存布局(上)
本文转载自haoel博主的博客:陈皓专栏 [空谷幽兰,心如皓月] 原文地址:C++ 对象的内存布局(上) C++ 对象的内存布局(上) 陈皓 http://blog.csdn.net/haoel 点击 ...
- JVM总结-java对象的内存布局
在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我们还可以通过反射机制.Object.clone 方法.反序列化以及 Unsafe.allocateInstance ...
- Java对象创建的过程及对象的内存布局与访问定位
这里以HotSpot为例,且所说的对象指普通的Java对象,不包括数组和Class对象等. 1.对象创建的过程 1.类加载.解析.初始化:虚拟机遇到new时先检查此指令的参数是否能在常量池中找到类的符 ...
- JVM中对象的内存布局与访问定位
一.对象的内存布局 已主流的HotSpot虚拟机来说, 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填 ...
随机推荐
- 第2章 如何构建布局良好的Windows程序
01.菜单栏(MenuStrip) 设置快捷键方式: 方式一:1.设置菜单项的Text属性为(打开(&F)), 首先必须按住alt+主菜单快捷键进入到对应的主菜单, 然后直接按F就可以打开子窗 ...
- 小清新的jQuery ck-slide 图片轮播
ck_slide 是一款小清新的jQuery 幻灯片插件,它非常小巧,压缩后仅 3KB,基本功能可以满足.它支持淡入淡出/左右滚动.箭头/圆点控制.自动播放. 在线实例 默认(淡入淡出) 左右滚动 自 ...
- jQuery cxSlide 焦点图轮换
cxSlide 是一个简单易用的焦点图展示插件,支持水平.纵向切换,透明过渡切换. 已支持 CSS 动画过渡切换.通过 CSS 动画切换,可以展示更多效果. 版本: jQuery v1.7+ jQue ...
- jQuery 浮动标签插件,帮助你提升表单用户体验
浮动标签模式(Float Label Pattern)是最新流行的一种表单输入域的内容提示方式,当用户在输入框输入内容的时候,原先占位符的内容向上移动,显示在输入的内容的上面.这里推荐的这款 jQue ...
- 灵感来自 Google & YouTube 的苗条的进度栏效果
NProgress.js 是纳米级的进度条插件.拥有逼真的的涓涓细流动画效果来告诉你的用户,某些事情正在发生.它的灵感来自于谷歌,YouTube,应用了,这款苗条的进度条是完美的,适用于 Turbol ...
- 带给您灵感的25个最新鲜的 HTML5 网站
感谢 HTML5 带来的惊人的先进特性,在未来几年,HTML5 将会继续发挥巨大的推动作用,不仅是在 Web 应用中,网页设计领域也会有新的变革.今天,我们在这里集合了能够带给您灵感的25个最新鲜的 ...
- [js开源组件开发]loading加载效果
loading加载效果 由于程序和网络的原因,常常我们需要在交互的时候,给用户一个正在加载中的动画,于是,loading组件横空出世.不需要复杂的代码,也能完成大多数业务,这就是我做组件的原则. 效果 ...
- js引入php 用来加载静态页面 输出到页面中
HTML页面中加入代码 <script type="text/javascript" src="http://www.域名.com/js.php?id=tjyd&q ...
- 【Bootstrap】1.初识Bootstrap
作为Web前端开发框架,Bootstrap为大多数标准的UI设计常见提供了用户友好.扩浏览器的解决方案. 1.下载Bootstrap 打开官方网址 http://getbootstrap.com/ 进 ...
- 当SD卡拔出时,返回首页,栈中的activity都要清除,只留下首页的activity
目标:当SD卡拔出时,返回首页,栈中的activity都要清楚,只留下首页的activity 我在清单中注册了一个静态广播: <receiver android:name="com.p ...