托管堆分配资源:
一:进程初始化是,CLR要保留一块联系的地址空间,这个地址空间最初并没有对应的物理存储空间。这个地址空间就是托管堆。托管堆还维护着一个指针,我把它称为NextObjPtr。它指向下个对象在堆中的分配位置。刚开始的时候NextObjPtr设为要保留地址空间的基地址。 IL指令newobj用于创建一个对象:
① 计算所有类型及其所有基类型的字段需要的字节数。
② 加上对象开销所需要的字节数。每个对象都有两个开销字段,一个是类型对象指针,和一个同步快索引。对于32应用程序各自需要32位,所以每个对象和要增加8字节。对于64位应用程序中,这每个字段个需要64位,所以每个对象要增加16字节。
③ CLR检查保留区域示范能够提供分配对象所需要的字节数,如有必要就提交存储。如果托管堆有足够的可以空间,对象就会被放入。注意对象是在NextObjPtr指针指向的地址放入的,并且为他分配的字节会被清零。接着,调用类型的实例构造器(为this参数传递NextObjPtr),IL指令newobj(或者C# new操作符)将返回对象的地址,就在地址返回之前,NextObjPtr指针的值会加上对象占据的字节数,这样会得到一个新值,它指向下一个对象放入托管堆的地址。 运行时堆是如何分配内存的:
在对象C运行时堆中,为对象分配内存需要遍历一个由数据结构组成的链表。一旦发现一个足够大的款,那个块就会被拆分,同时修改链表节点中的指针,以确保链表的完整性。从托管堆分配对象的速度几乎可与线程栈分配内存媲美。另外,大多数堆都是在他们找到可用空间的地方分配对象。所以,如果连续创建了几个对象,他们极有可能被分散,中间相隔数MB的地址空间,但在托管堆中,连续分配的对象可用确保他们在内存中是连续的。 垃圾回收器的工作原理:
应用程序调用new操作符创建对象时,可能没有足够的地址空间来来分配该对象。托管堆将对象需要的字节数加到NextObjPtr指针中的地址上来检测这种情况。如果结果值超过了地址空间的末尾,表明托管堆已满,必须执行一次垃圾回收。
垃圾回收是在第0代满的时候发生的。有的垃圾回收器使用了代的机制,该机制唯一的目的就是提升性能。其基本思路:在应用程序的生成周期中,新建的对象是新一代,二创建的比较早的是老一代。第0代是最近分配的对象,从未被垃圾回收器算法检查过。在辣鸡回收器中存活下来的对象提升到另一代(例如第一代),将对象划分为代,使辣鸡回收器能专注于回收特定的代,而不是每次都要回收托管堆这的所有对象。
代:①对象越新,生存期越短 ②对象越老,生存期越长 ③回收对的一部分,速度快于回收整个堆。托管堆在初始化时不包含任何对象。添加到堆的对象称为第0代对象。简单的说,第0代对象就是那些新构造的对象,垃圾回收器从未检查过他们。CLR初始化时,它会为第0代对象选择一个预算容量。如果分配一个新对象造成第0代超过预算,就必须启动一次垃圾回收。经过一次垃圾回收后,第0代幸存者提升至1代,第0代暂时是空的。每次垃圾回收的时候,第一代的大小增加。当第一代内存已满,则进行清理,同时第一代提升为第二代。
CLR的托管堆只支持三代:第零代,第一代,第二代,CLR初始化时会为每一代选择预算。垃圾回收器发现第0代,需要回收的垃圾非常多时,就会减小第0代的内存,频繁进行垃圾回收。如果0代需要回收的垃圾非常少时,就会减少垃圾回收,加大内存。

.Net之托管堆资源分配的更多相关文章

  1. 【CLR】解析CLR的托管堆和垃圾回收

    目录结构: contents structure [+] 为什么使用托管堆 从托管堆中分配资源 托管堆中的垃圾回收 垃圾回收算法 代 垃圾回收模式 垃圾回收触发条件 强制垃圾回收 监视内存 对包装了本 ...

  2. cir from c# 托管堆和垃圾回收

    1,托管堆基础 调用IL的newobj 为资源分配内存 初始化内存,设置其初始状态并使资源可用.类型的实列构造器负责设置初始化状态 访问类型的成员来使用资源 摧毁状态进行清理 释放内存//垃圾回收期负 ...

  3. 【C#进阶系列】21 托管堆和垃圾回收

    托管堆基础 一般创建一个对象就是通过调用IL指令newobj分配内存,然后初始化内存,也就是实例构造器时做这个事. 然后在使用完对象后,摧毁资源的状态以进行清理,然后由垃圾回收器来释放内存. 托管堆除 ...

  4. C#中的托管堆和堆栈

    托管堆(Heap)和堆栈(Stack)是内存的逻辑划分.   栈 堆 连续性 连续 不连续 有序性 后进先出 无序 内存管理 操作系统自动释放 GC或人工 存放类型 值类型/引用 引用类型 注:内存格 ...

  5. C#堆栈和托管堆

    首先堆栈和堆(托管堆)都在进程的虚拟内存中.(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型. 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充. 堆栈的工作方式 ...

  6. .NET 托管堆和垃圾回收

       托管堆基础 简述:每个程序都要使用这样或那样的资源,包括文件.内存缓冲区.屏幕空间.网络连接.....事实上,在面向对象的环境中,每个类型都代表可供程序使用的一种资源.要使用这些资源,必须为代表 ...

  7. 栈和托管堆/值类型和引用类型/强制类型转换/装箱和拆箱[C#]

    原文地址:http://www.cnblogs.com/xy8.cn/articles/1227228.html 一.栈和托管堆      通用类型系统(CTS)区分两种基本类型:值类型和引用类型.它 ...

  8. .Net 类型、对象、线程栈、托管堆运行时的相互关系

    JIT(just in time)编译器 接下来的会讲到方法的调用,这里先讲下JIT编译器.以CLR书中的代码为例(手打...).以Main方法为例: static void Main(){ Cons ...

  9. .NET中 类型,对象,线程栈,托管堆在运行时的关系

    .NET中 类型,对象,线程栈,托管堆在运行时的关系 The Relationship at Run Time between Types,Objects,A Thread's Stack,and T ...

随机推荐

  1. 纪念SlingShot 矩阵

    第一次独立做矩阵,只WA了一次,好高兴~~ 题意:已知 F(n)=3 * F(n-1)+2 * F(n-2)+7 * F(n-3),n>=3,其中F(0)=1,F(1)=3,F(2)=5,对于给 ...

  2. apache配置gzip模式(转)

    最近在看有关提高website性能的书,个人觉得挺不错的两本书: <<high performance websites>> <<even faster websi ...

  3. Python之路第六天,基础(7)-正则表达式(re)

    Python RE模块(正则表达式) 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成 ...

  4. IEnumerable

    C#基础之IEnumerable 1.IEnumerable的作用 在使用Linq查询数据时经常以IEnumerable<T>来作为数据查询返回对象,在使用foreach进行遍历时需要该对 ...

  5. JavaScript 问答 - No.1

    1     什么是JavaScript? JavaScript 是世界上最流行的脚本语言. JavaScript 是属于 web 的语言,它适用于 PC.笔记本电脑.平板电脑和移动电话. JavaSc ...

  6. QProgressBar和QProgressDialog的简单实用

    在QT中可以用QProgressBar或着QProgressDialog来实现进度条. QProgressBar的使用 首先在designer中拖一个按钮和进度条部件,按下面初始化 ui->pr ...

  7. [置顶] Oracle GoldenGate 系列:使用 Oracle ASM API DBLOGREADER 时遇 ora-01031 错误

    今天在自己新搭建的 Oracle ACFS 文件系统上测试 GoldenGate ,启动 extract 进程报如下错误: 2013-08-27 14:58:39  ERROR   OGG-00446 ...

  8. perl 调用按钮输出到文本框

    sub push_b4 { #$txt -> insert('end'); #select $txt; system("expect c:\\\\expect.txt >expe ...

  9. c++ 17介绍

    作者:hearts zh链接:https://www.zhihu.com/question/32222337/answer/55238928来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商 ...

  10. linux之普通用户与root用户之间切换