自动内存管理是公共语言运行时在托管执行过程中提供的服务之一。公共语言运行时的垃圾回收器为应用程序管理内存

的分配和释放。对开发人员而言,在开发托管应用程序时不必编写执行内存管理任务代码。

分配内存

初始化新进程时,运行时会为进程保留一个连续的地址空间区域。这个保留的地址空间被称为托管堆。托管堆维护着一个指针,用它指向堆中分配的下一个对象的地址。初始时,该指针设置为指向托管堆的基础地址。托管堆上包含所有的引用类型。应用程序在创建第一个引用类型时,将为托管堆的基址中的类型分配内存。应用程序创建下一个对象时,垃圾回收器在紧接第一个对象后面的地址空间内为它分配内存。只要地址空间可用,垃圾回收器就会继续以这种方式为新对象分配空间。

在托管堆中分配内存要比非托管堆内存分配速度快。由于运行时通过为指针添加值来为对象分配内存,这个速度几乎与堆栈中分配内存一样快。另外由于连续分配的新对象在托管堆中是连续存储,所以应用程序可以快速访问这些对象。

释放内存

垃圾回收器的优化引擎根据所执行的分配决定执行回收的最佳时间。垃圾回收器在执行回收时,会释放应用程序不再使用的对象的内存。它通过检查应用程序的根来确定不再使用的对象。每个应用程序都有一组根。每个根或者引用托管堆中的对象设置为空。应用程序的根包含线程堆栈上的静态字段、局部变量和参数以及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知识点回顾]-自动内存管理的更多相关文章

  1. iOS----ARC(自动内存管理)

    1.ARC是什么呢,有什么用? ARC是苹果官方推出的帮助我们苹果开发工程师管理内存的一种自动内存管理机制,它的前身是MRC,也就是手动内存管理: 2.ARC的基本原理是什么? ARC是编译器(时)特 ...

  2. 垃圾回收算法手册:自动内存管理的艺术 BOOK

    垃圾回收算法手册:自动内存管理的艺术 2016-03-18 华章计算机 内容简介 PROSPECTUS 本书是自动内存管理领域的里程碑作品,汇集了这个领域里经过50多年的研究沉积下来的最佳实践,包含当 ...

  3. cocos2d-x学习之自动内存管理

    一.自动内存管理 1)概述 C++语言默认是没有提供自动内存管理的.使用者需要自己分配,自己释放.在cocos2d-x里提供了一个自动内存管理的方案.主要是通过CCObject来提供的,用户只要继承了 ...

  4. JVM自动内存管理学习笔记

    对于使用 C.C++ 的程序员来说,在内存管理领域,他们既是拥有最高权力的皇帝又是从事最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任.对于 Java 程 ...

  5. Xcode 如何设置 自动内存管理 转换为 手动内存管理

    建议使用自动内存管理 ARC. 如果不想自动内存管理,可以在build phases 下的compile sources 中找到不想自动管理的.m文件 ,给它加compiler flags 为 -fn ...

  6. JVM自动内存管理-Java内存区域与内存溢出异常

    摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...

  7. JVM介绍&自动内存管理机制

    1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...

  8. oracle11g自动内存管理

    Oracle一直不停的在为Orace数据库的自动化管理努力着,11G中的自动内存管理是Oracle数据库中又一新的里程碑,通过新参数MEMORY_TARGET 来代替PGA和SGA的配置,ORACLE ...

  9. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

随机推荐

  1. [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle

    [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle 目录 [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Ming ...

  2. java中基本数据类型、包装类及字符串之间的相互转换

    基本数据类型:不支持面向对象的编程机制(没有属性和方法),即不支持面向对象,之所以提供8中基本数据类型,是为了方便常规数据的处理. 包装类:通过包装类可以将基本数据类型的值包装为引用数据类型的对象,使 ...

  3. [bug] idea @Override is not allowed when implementing interface method

    解决 将idea环境jdk设置一致 参考 https://blog.csdn.net/shenya2/article/details/50460447 https://www.cnblogs.com/ ...

  4. [bug] Window远程连接hdfs错误:java.lang.UnsatisfiedLinkError: org.apache.hadoop.util.NativeCrc32.nativeComput

    原因 hadoop.dll 版本问题 解决 查询远程主机中hadoop版本,下载相同或稍高版本的hadoop.dll,将下载的 hadoop.dll 复制到windows系统的c:/window/sy ...

  5. 华为交换机Console口属性配置

    华为交换机Console口属性配置 一.设置通过账号和密码(AAA验证)登陆Console口 进入 Console 用户界面视图 <Huawei>system-view [Huawei]u ...

  6. mysql基础之数据库备份和恢复的基础知识

    备份数据的最终目的是为了在出现一些意外情况时,能够通过备份将数据还原,所以单单的备份数据往往是无法满足还原时的需求的,所以在备份数据库时,除了要备份数据本身,还要备份相关的数据库环境,如配置文件,定时 ...

  7. JDK、JRE 和 JVM 的区别

    JDK JDK 是 Java Development Kit 的缩写,JDK 是 Java 语言的软件开发工具包( SDK ).它提供了Java 开发.编译.运行需要的文件和环境. 如果你是 Java ...

  8. java基础之8种基本数据类型

    简单往往是最重要的,在刚刚学java的时候老师会给我们先讲这8种基本数据类型,今天再来做一个温习,[本文大部分参考了 https://zhuanlan.zhihu.com/p/25439066,在上面 ...

  9. 西门子 S7300 以太网模块连接组态王方法

    北京华科远创科技有限研发的远创智控ETH-YC模块,以太网通讯模块型号有MPI-ETH-YC01和PPI-ETH-YC01,适用于西门子S7-200/S7-300/S7-400.SMART S7-20 ...

  10. Hadoop 基石HDFS 一文了解文件存储系统

    @ 目录 前言:浅谈Hadoop Hadoop的发展历程 1.1 Hadoop产生背景 1.引入HDFS设计 1.1 HDFS主要特性 2.HDFS体系结构 HDFS工作流程机制 1.各个节点是如何互 ...