.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 ...
随机推荐
- 将json格式日期(毫秒数)转成日常日期格式和日常格式时间对比
第一:是把生成的Json格式的时间转换,注意要看清楚时间的格式 function (cellval) { var date = new Date(parseInt(cellval.replace(&q ...
- Z - 不容易系列之(3)―― LELE的RPG难题
Description 人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即"可乐"),经过多方打探,某资深C ...
- vim中使用gdb。
引用文章A:http://easwy.com/blog/archives/advanced-vim-skills-vim-gdb-vimgdb/ 引用介绍:使用vimgdb来完成gdb的嵌入. 需要的 ...
- java教程
http://www.xfonlineclass.com/ http://java.itcast.cn/ http://www.xasxt.com/index.php/list/161 [UI]htt ...
- go pprof
import _ "net/http/pprof" func main() { go func() { http.ListenAndServe("localhost:60 ...
- C# Winform程序本地化应用
1. 创建一个WinForm应用程序 – “WindowsFormsLocalizationTest”. 2. 在主窗体属性栏里,把Localizable属性设置成”True”. 3. 添加两个But ...
- [Head First Python]1. 初始python-人人都爱列表
movies = [ "hello", "world",["xin","lover",["Jerry" ...
- 自定义View 一 (继承VIew重写onDraw方法)
项目:具有圆形效果的自定义View 一.继承View并重写onDraw方法 public class CircleView extends View{ private static final int ...
- Change the ball--hdu2277
Change the ball Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HeadFirst设计模式读书笔记(4)-工厂模式
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个.工厂方法让类把实例化推迟到子类. 所有工厂模式都用来封装对象的创建.工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象 ...