[.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) ...
随机推荐
- XCTF.MISC 新手篇
目录 泪目 1.this_is_flag 2.pdf 3.如来十三掌 4.give_you_flag 5.坚持60s 6.gif 7.掀桌子 8.ext3 9.stegano 10.SimpleRAR ...
- opencv——图像直方图与反向投影
引言 在图像处理中,对于直方图这个概念,肯定不会陌生.但是其原理真的可以信手拈来吗? 本文篇幅有点长,在此列个目录,大家可以跳着看: 分析图像直方图的概念,以及opencv函数calcHist()对于 ...
- kubernetes客户端client-go使用
下载地址: https://github.com/kubernetes/client-go 官方使用文档参考:https://v1-16.docs.kubernetes.io/docs/referen ...
- [笔记] 《c++ primer》显示器程序 Chapter7
补充Sales_data没有体现出的其他类特性 Screen.h 1 #include <string> 2 #include <iostream> 3 4 class Scr ...
- FireFox-background
- rsync+inotify实现全网自动化数据备份
第1章 环境配置 实例1-1 服务器及IP主机名规划 已知 4 台服务器主机名主机对应信息见下表: 服务器说明 外网 IP(NAT) 内网 IP(NAT) 主机名 web服务器 10.0.0.7/2 ...
- 利用jink的驱动软件j-flash 合并两个hex的方法,bootloader+app -(转载)
第一步:先打开第一个hex文件, 第二步:选择 "Merge data file",合并文件 第三步:两个工程有可能地址相同,会有如下提示:(如果在编译的时候设置好Flash的地址 ...
- 9.4-6 kill & killall & pkill
kill:终止进程 能够终止你希望停止的进程. kill 命令的参数选项及说明 -l 列出全部的信号名称 -p 指定kill命令只打印相关进程的进程号,而不发送任何信号 -s 指定要 ...
- MYSQL导入/迁移后事件不执行
mysql迁移后事件不执行 查看数据库是否开启事件支持 mysql> show variables like 'event_scheduler'; +-----------------+---- ...
- SqlServer事务详解(事务隔离性和隔离级别详解)
概述 不少人对于事务的使用局限于begin transaction:开始事务.commit transaction:提交事务.rollback transaction:回滚事务的初步运用. 并且知道使 ...