.Net之托管堆资源分配
托管堆分配资源:
一:进程初始化是,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之托管堆资源分配的更多相关文章
- 【CLR】解析CLR的托管堆和垃圾回收
目录结构: contents structure [+] 为什么使用托管堆 从托管堆中分配资源 托管堆中的垃圾回收 垃圾回收算法 代 垃圾回收模式 垃圾回收触发条件 强制垃圾回收 监视内存 对包装了本 ...
- cir from c# 托管堆和垃圾回收
1,托管堆基础 调用IL的newobj 为资源分配内存 初始化内存,设置其初始状态并使资源可用.类型的实列构造器负责设置初始化状态 访问类型的成员来使用资源 摧毁状态进行清理 释放内存//垃圾回收期负 ...
- 【C#进阶系列】21 托管堆和垃圾回收
托管堆基础 一般创建一个对象就是通过调用IL指令newobj分配内存,然后初始化内存,也就是实例构造器时做这个事. 然后在使用完对象后,摧毁资源的状态以进行清理,然后由垃圾回收器来释放内存. 托管堆除 ...
- C#中的托管堆和堆栈
托管堆(Heap)和堆栈(Stack)是内存的逻辑划分. 栈 堆 连续性 连续 不连续 有序性 后进先出 无序 内存管理 操作系统自动释放 GC或人工 存放类型 值类型/引用 引用类型 注:内存格 ...
- C#堆栈和托管堆
首先堆栈和堆(托管堆)都在进程的虚拟内存中.(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型. 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充. 堆栈的工作方式 ...
- .NET 托管堆和垃圾回收
托管堆基础 简述:每个程序都要使用这样或那样的资源,包括文件.内存缓冲区.屏幕空间.网络连接.....事实上,在面向对象的环境中,每个类型都代表可供程序使用的一种资源.要使用这些资源,必须为代表 ...
- 栈和托管堆/值类型和引用类型/强制类型转换/装箱和拆箱[C#]
原文地址:http://www.cnblogs.com/xy8.cn/articles/1227228.html 一.栈和托管堆 通用类型系统(CTS)区分两种基本类型:值类型和引用类型.它 ...
- .Net 类型、对象、线程栈、托管堆运行时的相互关系
JIT(just in time)编译器 接下来的会讲到方法的调用,这里先讲下JIT编译器.以CLR书中的代码为例(手打...).以Main方法为例: static void Main(){ Cons ...
- .NET中 类型,对象,线程栈,托管堆在运行时的关系
.NET中 类型,对象,线程栈,托管堆在运行时的关系 The Relationship at Run Time between Types,Objects,A Thread's Stack,and T ...
随机推荐
- JavaScript模块化开发&&模块规范
在做项目的过程中通常会有一些可复用的通用性功能,之前的做法是把这个功能抽取出来独立为一个函数统一放到commonFunctions.js里面(捂脸),实现类似于snippets的代码片段收集. fun ...
- 计算一个数组里的重复值并且删去(java)
主要思想: 数组可以无序 假设数字里的值都为正 循环判断数组 如果与前面的数字相同则变为-1 然后记录-1的个数算出重复值 然后重新new一个减去重复值长度的新数组 和原数组判断 不为-1的全部复制进 ...
- <转>科普CPU Cache line
转载于http://coolshell.cn/articles/10249.html CPU cache一直是理解计算机体系架构的重要知识点,也是并发编程设计中的技术难点,而且相关参考资料如同过江之鲫 ...
- jquery.form上传文件
建立test文件夹 PHP代码: <?php //var_dump($_FILES['file']);exit; if(isset($_GET['option']) && $_G ...
- HDU 1056 - HangOver
递推 #include <iostream> using namespace std; ]; double c; int main() { f[]=; ;i<=;i++) f[i]= ...
- Java并发编程小记
1. Semaphore 信号量是一种计数器,用来保护一个或者多个共享资源的访问.如果线程要访问一个共享资源,必须先获得信号量.若内部计数器大于0,则减1,若等于0,则线程进入休眠直至计数器大于等于0 ...
- 检测delphi的程序的内存泄漏
在主窗体的FormCreate 加入ReportMemoryLeaksOnShutdown := True;
- Git for PyCharm
Git for PyCharm Using PyCharm's Git integration locally:http://confluence.jetbrains.com/display/PYH/ ...
- MVC4商城项目一:框架设计
代码已托管在 https://code.csdn.net/denghao156/ktnmb_mvc4 先上图,设计模式参考:ddmvc4.codeplex.com 一.unintofwork 设计 ...
- 关于采用MVC开发默认路由导致首页部分文件访问失效的临时解决方案
最近开发中涉及了Mvc4的开发,其中的默认路由功能是很不错的东西,但是在实际应用中就出现了不少的问题.比如我们访问某网站http://www.abc.com,虽然路由会帮助自动转向Home/Index ...