知识大全 内存分配
Posted 分配
篇首语:不操千曲而后晓声,观千剑而后识器。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 内存分配相关的知识,希望对你有一定的参考价值。
你必须知道的.NET:内存分配 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
在分析内存分配时 应该先了解关于堆栈的区别
堆的分配向高地址扩展 而栈的分配向低地址扩展
一 内存分配
关于内存的分配 首先应该了解分配在哪里的问题 CLR管理内存的区域 主要有三块 分别为
· 线程的堆栈 用于分配值类型实例 堆栈主要由操作系统管理 而不受垃圾收集器的控制 当值类型实例所在方法结束时 其存储单位自动释放 栈的执行效率高 但存储容量有限
· GC堆 用于分配小对象实例 如果引用类型对象的实例大小小于 字节 实例将被分配在GC堆上 当有内存分配或者回收时 垃圾收集器可能会对GC堆进行压缩 详情见后文讲述
- public class VIPUser:User //分配 Byte public bool isVip; public bool IsVipUser() return isVip; static void Main( string[] args) //分配内存空间和初始化操作 VIPUser aUser; //将对象引用赋给aUser变量 建立aUser和VIPUser的关联 aUser = new VIPUser(); //Q:类型的分配的字节数? //就本类而言需要 Byte 但是实例对象所占的字节总数还要加上对象附加成员所需的字节数 其中包括附加成员TypeHandle和SyncBlockIndex共 个字节 在托管堆上分配的字节总数为 字节 而堆上的内存块总是按照 Byte的倍数进行分配 因此本类中将分配 字节的地址空间 //最后调用对象构造器 进行对象初始化操作 完成创建 //构造过程 //a 构造VIPUser类型的Type对象 主要包括静态字段 方法表 实现的接口等 并将其分配在上文提到托管堆的Loader Heap上 //b 初始化aUser的两个附加成员 TypeHandle和SyncBlockIndex 将TypeHandle指针指向Loader Heap上的MethodTable CLR将根据TypeHandle来定位具体的Type 将SyncBlockIndex指针指向Synchronization Block的内存块 用于在多线程环境下对实例对象的同步操作 //c 调用VIPUser的构造器 进行实例字段的初始化 实例初始化时 会首先向上递归执行父类初始化 直到完成System Object类型的初始化 然后再返回执行子类的初始化 直到执行VIPUser类为止 以本例而言 初始化过程为首先执行System Object类 再执行User类 最后才是VIPUser类 最终 newobj分配的托管堆的内存地址 被传递给VIPUser的this参数 并将其引用传给栈上声明的aUser aUser isVip = true; Console WriteLine(aUser IsVipUser()); //上述过程 基本完成了一个引用类型创建 内存分配和初始化的整个流程 public class UserInfo //分配 个字节 private Int age = ; //分配 个字节 private char level = A ; public class User //分配 byte private Int id; //保存了UserInfo的引用 占用 Byte //仅是一个引用(指针) 保存在线程的堆栈上 占用 Byte的内存空间 用于保存user对象的有效地址 现在试图对user的任何操作将抛出NullReferenceException private UserInfo user;
LOH(Large Object Heap)堆 用于分配大对象实例 如果引用类型对象的实例大小不小于 字节时 该实例将被分配到LOH堆上 而LOH堆不会被压缩 而且只在完全GC回收时被回收
在了解内存分配之前 首先了解一下三个概念
TypeHandle 类型句柄 指向对应实例的方法表 每个对象创建时都包含该附加成员 并且占用 个字节的内存空间 我们知道 每个类型都对应于一个方法表 方法表创建于编译时 主要包含了类型的特征信息 实现的接口数目 方法表的slot数目等
SyncBlockIndex 用于线程同步 每个对象创建时也包含该附加成员 它指向一块被称为Synchronization Block的内存块 用于管理对象同步 同样占用 个字节的内存空间
NextObjPtr 由托管堆维护的一个指针 用于标识下一个新建对象分配时在托管堆中所处的位置 CLR初始化时 NextObjPtr位于托管堆的基地址
二 继承本质论
- //Bird bird创建的是一个对象的引用 而new Bird()是创建Bird对象 分配内存和初始化操作 然后将对象引用赋给bird变量 也就是简历bird和Bird 之间的关联 Bird bird = new Bird(); // 从继承的角度来分析CLR在运行时如何执行对象的创建过程 // 首先是字段的创建 字段的存储顺序由上到下排列 最高层类的字段排在最前面 // 方法表的创建是类第一次加载到AppDomain时完成的 在对象创建时只是将其附加成员TypeHandle指向方法列表Loader Heap上的地址 将对象与其动态方法列表相关联起来 因此方法表示先于对象存在的 Chicken ch = new Chicken();
相关参考
Windows下动态内存分配方式 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 这里的动态内存包
JVM基础:JVM内存组成及分配 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nbs
配置JVM内存分配的妙招 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n
浅析SybaseSQLServer内存分配 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 我们知
SQLServer中动态和静态内存分配 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! SQL服务
深入Java核心Java内存分配原理精讲 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Java
为C++标准库容器写自己的内存分配程序 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &
销毁单链表 单链表被构造使用完后由于其结点均为动态分配的内存空间所以必须要销毁以释放空间否则会造成申请的内存不能释放单链表的销毁操作是创建操作的逆运算由于要修改单链表的头指针的指针变量所以要将头
JScript运行时错误JScript运行时错误是指当JScript脚本试图执行一个系统不能运行的动作时导致的错误当正在运行脚本计算变量表达式或者正在动态分配内存时出现JScript运行时错误时错误号
MyEclipse内存不足之JVM内存浅谈 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! MyE