[.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) ...
随机推荐
- 本地Markdown上传图片
本地Markdown上传图片 1.上传本地markdown文件到博客园 使用工具pycnblog 下载:https://github.com/dongfanger/PyCnblog 查看READ ME ...
- java基础——数组及其应用
数组 数组时相同类型数据的有序集合 数组描述的时相同类型的若干数据,按照一个定的先后次序排列组合而成 其中,每一个数据成为数组元素,每个数组元素可以通过一个下标来访问他们 数组的声明&创建 首 ...
- [项目] 淘淘商城 Part.1
电商 市场 2013:79万笔/分钟 2014:13.4万亿,双11支付宝交易峰值285万笔/分钟 2015:50万亿 技术特点 一个Tomcat:500并发 分布式:上万并发 高并发.集群.负载均衡 ...
- Linux命令行欢迎界面美化
默认的SSH命令行登录欢迎界面如下 [c:\~]$ Connecting to 10.x.13.x:22... Connection established. To escape to local s ...
- QT学习笔记(一)——Helloworld
QT学习笔记(一)--Helloworld 一.调试的基本方法: Log调试法 --在代码中加入一定的打印语句 --打印程序状态和关键变量的值 断点调试法: --在开发环境中的对应代码行加上断点 -- ...
- Ubuntu中的MySQL修改root密码的多种方法
查看.修改mysql的用户名和密码第一步:这时你需要进入/etc/mysql目录下,然后sudo vim/vi debian.cnf查看里面的用户名和密码,然后使用这个文件中的用户名和密码进入mysq ...
- 【Azure 事件中心】为应用程序网关(Application Gateway with WAF) 配置诊断日志,发送到事件中心
问题描述 在Application Gateway中,开启WAF(Web application firewall)后,现在需要把访问的日志输出到第三方分析代码中进行分析,如何来获取WAF的诊断日志呢 ...
- Mybatis3详解(十四)----Mybatis的分页
1.前言 在前面学习mybatis的时候,会经常对数据进行增删改查操作,使用最多的是对数据库进行查询操作,但是前面都是简单的案例,所以查询的数据量不是很大,自然查询时没有任何压力,但是如果在实际的项目 ...
- Cannot resolve class or package 'mysql’处理方法
在application.properties中配置mybatis_plus碰见报了这个错误 Cannot resolve class or package 'jdbc' 错误产生的原因 其实这个问题 ...
- 永远的Ace 团队作业4—团队项目需求建模与系统设计(1)
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST/ 这个作业要求链接 https://www.cnblogs.com/nwnu-da ...