.net 内存分配及垃圾回收总结
生存期垃圾回收器
目前有很多种类型的垃圾回收器.微软实现了一种生存期垃圾回收器(Generation Garbage Collector).
生存期垃圾回收器将内存分为很多托管堆,每一个托管堆对应一个生存期等级。
垃圾回收器目前有三个生存期等级,这里我们称作代,0代,1代,2代,GC中0代是最年轻的对象,2代对象存活的时间最长,GC按代回收垃圾出于性能考虑,通常对象会在0代被回收.

在应用程序初始化之前,所有等级的托管堆都是空的,当对象初始化的时候,他们会按照初始化的先后顺序被放入0代的托管堆中(有例外)。在托管堆中对象是连续存放的,垃圾回收器中保存了一个指针指向托管堆中最后一个对象之后的内存空间

当0代托管堆超过了256K,垃圾回收器检查托管堆中的所有对象,看是否有对象可以回收.
当开始回收时,垃圾回收器找出被继续引用的对象,将这些对象转1代托管堆中,并将0代托管堆的指针移动到开始的位置清除所有的对象,并压缩1代托管堆以保证所有对象之间没有空隙
1代托管堆满了之后,或者1代托管堆没有被垃圾回收器回收,会转移到2代的托管堆

当对象被转移到2代的时候,2代不会被垃圾回收器进行压缩,碎片整理

大对象堆和小对象堆
垃圾回收器根据所占空间大小划分大对象堆和小对象堆,如果一个对象的大小超过85000byte,就认为是一个大对象,当一个对象申请内存大小达到这个阀值,它就会被分配到大对象堆上.
从代的角度看,大对象堆属于2代堆,所以2代堆也叫大对象堆(LOH,large object head),小对象堆(SOH,small object heap)属于0代和1代;前面我们说过2代堆被回收后剩下的对象不会被进行碎片整理,也就是说大堆相对不会被压缩和整理

1,小对象堆释放后,剩下的对象会被碎片整理,压缩合并
2,大对象堆释放后,无效内存留下的空间如果相邻就会被合并,如果不相邻就会单独空在那里;
3,当分配一个大对象时,运行时会优先尝试在LOH的尾部进行分配,如果尾部空间不足,就会尝试向操作系统请求更多的内存空间,只有在这一步也失败时才会重新搜索之前无效对象留下的内存空隙.
下面是大对象堆内存分配问题:


上面的图:
1,LOH中已经存在一个大小为85K的对象和一个大小为16M对象,当需要分配另外一个大小为85K的对象,会在尾部空间;
2,此时发生了一次垃圾回收,大小为16M的对象被回收,其占用的空间为未使用状态,但运行时并没有对LOH进行压缩。
3,此时再分配一个大小为16.1M的对象时,分尝试在LOH尾部分配.但尾部空间不足,所以运行时向操纵系统请求额外的内存,并将对象分配在尾部.
4,此时如果再需要分配一个大小为85K的对象,则优先使用尾部的空间.
OutOfMemoryException内存溢出问题:
当我们每次往后面申请的内存都比前面的大的时候
最后向系统申请内存申请不到,前面也没有任何一块连续区域满足要求时,就会出现内存溢出的问题

大对象什么时候回收:
1,申请的空间超过0代内存大小或者大对象堆的阀值,多数的托管堆垃圾回收在这种情况发生
2,在程序代码中调用GC.Collect方法时;如果在调用GC.Collect方法是传入GC.MAXGeneration参数时,会执行所有代对象的垃圾回收,包括大对象堆的垃圾回收
3,操作系统内存不足时,当应用程序收到操作系统发出的高内存通知时,
4,如果垃圾回收算法认为做二代回收是有收效时会触发二代垃圾回收
解决大对象堆溢出问题
2.尽量“重用”少量的大对象,而不是分配很多大对象;
3.当大对象回收比较慢的时候,可以选择做强制垃圾回收,但频繁回收大对象会损耗系统性能
.net 内存分配及垃圾回收总结的更多相关文章
- JVM内存分配与垃圾回收机制管理
项目上线,性能优化有个重要组成就是jvm内存分配和垃圾回收机制的管理配置. 网上随便能搜到相关的具体步骤,以及内存中各种参数对应的意义,不再赘述. 干货就是直接抛出遇到的问题,以及如何解决的,再说说待 ...
- CLR、内存分配和垃圾回收
一.CLR CLR:即公共语言运行时(Common Language Runtime),是中间语言(IL)的运行时环境,负责将编译生成的MSIL编译成计算机可以识别的机器码,负责资源管理(内存分配和垃 ...
- 浅谈JVM内存分配与垃圾回收
大家好,我是微尘,最近又去翻了周志明老师的<深入理解Java虚拟机>这本书.已经看了很多遍了,每次都感觉似乎看懂了,但没过多久就忘了.这次翻了第三章的垃圾收集器与内存分配策略,感觉有了新的 ...
- JVM的内存分配与垃圾回收策略
自动内存管理机制主要解决了两个问题:给对象分配内存以及回收分配给对象的内存. >>垃圾回收的区域 前面的笔记中整理过虚拟机运行数据区,再看一下这个区域: 注意在这个Runtime Data ...
- java内存分配与垃圾回收
JVM的内存分配主要基于两种,堆和栈. 我们来看一下java程序运行时候的内存分配策略: 1):静态存储区(方法区): 2):栈区: 3):堆区: 1):主要存放静态数据,全局static数据和常量. ...
- Java 内存分配及垃圾回收机制初探
一.运行时内存分配 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则 ...
- JVM 内存分配和垃圾回收(GC)机制
一 判断对象是否存活 垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“活着”,哪些已经"死去”,即不能再被任何途径使用的对象. 1.1 引用计数法 (Reference ...
- JVM内存分配和垃圾回收以及性能调优
JVM内存分配策略 一:堆中优先分配Eden 大多数情况下,对象都在新生代的Eden区中分配内存.而新生代会频繁进行垃圾回收. 二:大对象直接进入老年代 需要大量连续空间的对象,如:长字符串.数组等, ...
- JVM性能调优(3) —— 内存分配和垃圾回收调优
前序文章: JVM性能调优(1) -- JVM内存模型和类加载运行机制 JVM性能调优(2) -- 垃圾回收器和回收策略 一.内存调优的目标 新生代的垃圾回收是比较简单的,Eden区满了无法分配新对象 ...
随机推荐
- Android的消息处理机制,handler,message,looper(一)
当应用程序启动时,Android首先会开启一个主线程(也就是UI线程),主线程为管理界面中的UI控件.在程序开发时,对于比较耗时的操作,通常会为其开辟一个单独的线程来执行,以尽可能减少用户的等待时间. ...
- 用github pages展示你的静态网页,多项目支持
我看到有分享用github pages来做博客的,不过我并不想挂博客在上面,我只是想将我的一些作品挂上去,然后链接到我的简历里,这样HR可以直接看到. 首先是最基本的操作,在github上创建一个新的 ...
- 自己的3dmax作品RX-105柯西高达
背后视角带导弹仓. 侧面. 侧后视角. 前侧视角. 斜前上视角 使用关联实现骨骼功能,头.躯干.肩.上臂.前臂.手腕.手指.腰.髋关节.踝关节.脚掌皆由骨骼(是通过多边形关联实现骨骼功能,而不是使用3 ...
- Cocos2dx老版本适配64位
1.出现"__curl_rule_01__ "错误 解决方法: 下载新的第三方libcurl库.替换掉libcurl相关的库和头文件,libcul.a .h文件. 相关路径:co ...
- Effective Modern C++翻译(4)-条款3:了解decltype
条款3 了解decltype decltype是一个有趣的东西,给它一个变量名或是一个表达式,decltype会告诉你这个变量名或是这个表达式的类型,通常,告诉你的结果和你预测的是一样的,但是偶尔的结 ...
- 学习练习 java 二分查找法
package com.hanqi; import java.util.*; public class Test5 { public static void main(String[] args) { ...
- 洛谷P1198 [JSOI2008]最大数
P1198 [JSOI2008]最大数 267通过 1.2K提交 题目提供者该用户不存在 标签线段树各省省选 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 WA80的戳这QwQ BZOJ都 ...
- 关闭GS选项,解决注入后崩溃
利用CreateRemoteThread向进程注入远程代码时,一般会有以下两种做法: 利用LoadLibrary在目标进程加载指定的DLL 将代码复制到目标进程,然后启动这段代码 上面的第二种方法其实 ...
- MyEclipse简单设置
1.设置 安装完MyEclipse后,先设置工作空间的编码. Window—preferences—General--workspace—选择UTF-8编码 创建HTML的文件后,如果不是UTF- ...
- 通用简单的 分页 SQL
select ID,TITLE,CONTENT,USERNAME,REALNAME,UNIT,UNITID,NOWTIMES,ACCEPTERID,ACCEPTERNAM ...