[.NET Core知识点回顾]-自动内存管理
自动内存管理是公共语言运行时在托管执行过程中提供的服务之一。公共语言运行时的垃圾回收器为应用程序管理内存
的分配和释放。对开发人员而言,在开发托管应用程序时不必编写执行内存管理任务代码。
分配内存
初始化新进程时,运行时会为进程保留一个连续的地址空间区域。这个保留的地址空间被称为托管堆。托管堆维护着一个指针,用它指向堆中分配的下一个对象的地址。初始时,该指针设置为指向托管堆的基础地址。托管堆上包含所有的引用类型。应用程序在创建第一个引用类型时,将为托管堆的基址中的类型分配内存。应用程序创建下一个对象时,垃圾回收器在紧接第一个对象后面的地址空间内为它分配内存。只要地址空间可用,垃圾回收器就会继续以这种方式为新对象分配空间。
在托管堆中分配内存要比非托管堆内存分配速度快。由于运行时通过为指针添加值来为对象分配内存,这个速度几乎与堆栈中分配内存一样快。另外由于连续分配的新对象在托管堆中是连续存储,所以应用程序可以快速访问这些对象。
释放内存
垃圾回收器的优化引擎根据所执行的分配决定执行回收的最佳时间。垃圾回收器在执行回收时,会释放应用程序不再使用的对象的内存。它通过检查应用程序的根来确定不再使用的对象。每个应用程序都有一组根。每个根或者引用托管堆中的对象设置为空。应用程序的根包含线程堆栈上的静态字段、局部变量和参数以及CPU寄存器。垃圾回收器可以访问由实时编辑器(JIT)和运行时维护的活动根的列表。垃圾回收器对照此列表检查应用程序的根,并在此过程中创建一个图表,在其中包含所有可从这个根中访问的对象。
不在该图表中的对象无法从应用程序的根中访问。垃圾回收器会考虑无法访问的对象垃圾,并释放为他们分配内存。在回收中,垃圾回收器检查托管堆,查找无法访问对象占据的地址空间块。发现无法访问的对象时,它就使用复制功能来压缩内存中可以访问的对象。释放分配给不可访问对象的地址空间。在压缩了可访问对象的内存后,垃圾回收器就会做出指针更正,一边应用程序的根指向新地址中的对象。它会将托管堆指针定位至最后一个可访问对象以后。
注意:垃圾回收器只要发现大量无法访问的对象时,才会压缩内存。如果托管堆中的所有对象均未被回收,则不需要压缩内存。
为了改进性能,运行时(JIT)为单独堆中的大型对象分配内存。垃圾回收器会自动释放大型对象的内存。为了避免动内存中大型对象,不会压缩此内存。
级别和性能
为了优化垃圾回收器的性能,将托管堆分为三代:第0代,第1代,第2代。运行时的垃圾回收算法基于以下几个普通原理,这些垃圾回收方案的原理已在软件实验中得到验证。首先,压缩托管堆的一部分内存要比压缩整个托管堆速度块。其次,比较新对象生存期比较短,而比较老的对象生存期比较长。最后,比较新的对象趋向于相互关联,并同时由应用程序访问。
运行时的垃圾回收器将新对象存储在第0级中。在应用程序生存期的早期创建对象如果未被回收,则升级并存储在第1级和第2级中。
实际上,垃圾回收器在第0级托管堆已满时执行回收。如果应用程序在第0级托管堆已满时尝试新建对象,垃圾回收器将会发现第0级已没有可分配给对象地址空间。垃圾回收器就执行回收操作。释放第0级托管堆中的地址空间。垃圾回收器从第0级托管堆中的对象开始执行回收。
垃圾回收器执行第0级托管堆的回收后,会压缩可访问对象内存。然后垃圾回收器升级这些对象。并考虑第1级退管堆的这部分。因为未被回收的对象一般为比较长的生存期,所以将他们升级至更高级别。因此垃圾回收器每次回收第0级的托管堆,不会检查第1级和第2级托管堆中的对象。
在执行第0级托管堆的首次回收并把可访问的对象升级至第1级托管堆后,垃圾回收器将考虑第0级托管堆的其余部分。它将继续为第0级的托管堆中的新对象分配内存,直至第0级托管堆无法在分配地址后在执行另外一次的垃圾回收为止。此时,垃圾回收器的优化引擎会决定是否需要检测比较旧的级别中的对象。如:垃圾回收器发现0级托管堆中释放后的内存,不能再创建新的对象,垃圾回收器就会执行第1级托管堆的回收,然后再执行第2级托管堆的回收。如果这样仍不能回收足够的内存,垃圾回收器将执行第2,1和0级托管堆的回收。每次回收后,垃圾回收器都会压缩第0级托管堆中的可访问对象并将他们升级到第1级托管堆。第1级托管堆中未被回收的对象将会升级到第2级托管堆。由于垃圾回收器只支持三个级别,因此第2级托管堆中未被回收的对象继续保留再第2级托管堆中,直到在将来的回收中确定题目为无法访问为止。
为非托管资源释放内存
对于应用程序创建的大多数对象,可以依赖垃圾回收器自动执行必要的内存管理任务。但是,非托管资源需要显示清除。最常用的非托管堆资源类型时包装操作系统资源的对象,如:文件句柄,窗口句柄或网络连接。虽然垃圾回收器可以跟踪封装非托管堆资源的托管对象的生存期,但却无法具体了解如果清理资源。创建封装非托管资源的对象时,建议在公共Dispose方法中提供必要的代码用以清理非托管堆资源。通过提供Dispose方法,对象的用户可以在使用完对象后显示释放内存。使用封装非托管资源的对象时,应在不使用的时候调用Dispose()方法释放。
[.NET Core知识点回顾]-自动内存管理的更多相关文章
- iOS----ARC(自动内存管理)
1.ARC是什么呢,有什么用? ARC是苹果官方推出的帮助我们苹果开发工程师管理内存的一种自动内存管理机制,它的前身是MRC,也就是手动内存管理: 2.ARC的基本原理是什么? ARC是编译器(时)特 ...
- 垃圾回收算法手册:自动内存管理的艺术 BOOK
垃圾回收算法手册:自动内存管理的艺术 2016-03-18 华章计算机 内容简介 PROSPECTUS 本书是自动内存管理领域的里程碑作品,汇集了这个领域里经过50多年的研究沉积下来的最佳实践,包含当 ...
- cocos2d-x学习之自动内存管理
一.自动内存管理 1)概述 C++语言默认是没有提供自动内存管理的.使用者需要自己分配,自己释放.在cocos2d-x里提供了一个自动内存管理的方案.主要是通过CCObject来提供的,用户只要继承了 ...
- JVM自动内存管理学习笔记
对于使用 C.C++ 的程序员来说,在内存管理领域,他们既是拥有最高权力的皇帝又是从事最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任.对于 Java 程 ...
- Xcode 如何设置 自动内存管理 转换为 手动内存管理
建议使用自动内存管理 ARC. 如果不想自动内存管理,可以在build phases 下的compile sources 中找到不想自动管理的.m文件 ,给它加compiler flags 为 -fn ...
- JVM自动内存管理-Java内存区域与内存溢出异常
摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...
- JVM介绍&自动内存管理机制
1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...
- oracle11g自动内存管理
Oracle一直不停的在为Orace数据库的自动化管理努力着,11G中的自动内存管理是Oracle数据库中又一新的里程碑,通过新参数MEMORY_TARGET 来代替PGA和SGA的配置,ORACLE ...
- JVM自动内存管理机制——Java内存区域(下)
一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...
随机推荐
- Windows进程间通讯(IPC)----WM_COPYDATA
WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...
- 浅谈CRM系统的选型和实施
CRM的本质是最大化利用企业的现有资源来提供客户所需的产品,保证提供给客户最好的服务,帮助销售人员提高客户转化率,储存所有重要的客户信息,帮助企业深入挖掘潜在客户等等. 对于企业来说,即使处于同一行业 ...
- SprintBoot使用Validation
1.为什么要使用Validation 在开发过程中有没有使用一堆的if来判断字段是否为空.电话号码是否正确.某个输入是否符合长度等对字段的判断.这样的代码可读性差,而且还不美观,那么使用Validat ...
- [bug] C:warning: implicit declaration of function ‘getline’
参考 https://blog.csdn.net/loushuai/article/details/38983793
- Linux利用nc命令脚本批量检测服务器指定端口是否开放
一.nc命令检测端口的用法 # nc -v -w 10 %IP% -z %PORT% -v 显示指令执行过程. -w <超时秒数> 设置等待连线的时间. -u 表示使用UDP协议 -z 使 ...
- 强哥MySQL学习笔记
数据库服务器:1.数据库2.数据表 数据表:1.表结构(字段)2.表数据(记录)3.表索引(加快检索) 表引擎:1.myisam2.innodb 查看表字段desc table;删除数据库:drop ...
- 015.Python函数名的使用以及函数变量的操作
一 函数名的使用 python中的函数可以像变量一样,动态创建,销毁,当参数传递,作为值返回,叫第一类对象.其他语言功能有限 1.1 函数名是个特殊的变量,可以当做变量赋值 def func(): p ...
- MyBatis 动态 SQL 语句中出现 '<' 的问题
问题描述 映射接口方法如下: /** * 根据姓名和年龄查询用户信息 * @param name 姓名 * @param user 获取年龄 * @return */ public List<U ...
- 利用TortoiseGit向Github上传文件
利用TortoiseGit向Github上传文件 第一步:建一个新文件夹,作为本地仓库 第二步:右键选择设置为版本库 若弹出,确认即可 重新打开改文件,会发现多了一个绿色的小勾 在文件夹中会自动生成一 ...
- Nginx实战部署常用功能演示(超详细版),绝对给力~~~
前言 上次分享了一些开发过程中常用的功能,但如果到真实环境中,其实还需要一些额外的配置,比如说跨域.缓存.配置SSL证书.高可用等,老规矩,还是挑几个平时比较常用的进行演示分享.上篇详见Nginx超详 ...