.net 之内存回收

server/2024/9/23 3:56:32/

前言

一些基本概念如下:

托管代码

托管代码就是执行过程交由运行时管理的代码。 在这种情况下,相关的运行时称为公共语言运行时 (CLR),不管使用的是哪种实现(例如 Mono、.NET Framework 或 .NET Core/.NET 5+)。 CLR 负责提取托管代码、将其编译成机器代码,然后执行它。 除此之外,运行时还提供多个重要服务,例如自动内存管理、安全边界和类型安全。

非托管代码

如果运行 C/C++ 程序,则运行的代码也称为“非托管代码”。 在非托管环境中,程序员需要亲自负责处理相当多的事情。 实际的程序在本质上是操作系统 (OS) 载入内存,然后启动的二进制代码。 其他任何工作 - 从内存管理到安全考虑因素 - 对于程序员来说是一个不小的负担

非托管资源

使用完非托管资源后,必须显式释放这些资源。 最常用的非托管资源类型是包装操作系统资源的对象,如文件、窗口、网络连接或数据库连接

内存分配

每个进程都有其自己单独的虚拟地址空间。 同一台计算机上的所有进程共享相同的物理内存和页文件(如果有)

32 位计算机上的每个进程都具有 2 GB 的用户模式虚拟地址空间

  • 可能会存在虚拟地址空间碎片,这意味着地址空间中存在一些被称为孔的可用块。 当请求虚拟内存分配时,虚拟内存管理器必须找到满足该分配请求的足够大的单个可用块。 即使有 2 GB 可用空间,2 GB 分配请求也会失败,除非所有这些可用空间都位于一个地址块中。

  • 如果没有足够的可供保留的虚拟地址空间或可供提交的物理空间,则可能会用尽内存。

堆(Heap)

  • 堆内存是动态分配的。通过调用newmalloc等方法显式地分配内存,需要显式释放(如freedelete)。堆适合存储更大、更复杂的数据结构(如对象、数组)。
  • 内存管理更加灵活,但需要手动管理或依赖垃圾回收器。
托管堆

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

从托管堆中分配内存要比非托管内存分配速度快。 由于运行时通过为指针添加值来为对象分配内存,所以这几乎和从堆栈中分配内存一样快。

大对象堆(LOH)

大对象堆包含大小不少于 85,000 (约0.6M)个字节的对象,这些对象通常是数组。 非常大的实例对象是很少见的。

这个阀也是可以进行设置的

  • 该值可能由运行时限制为当前配置的最大可能大小。 可以通过 GC.GetConfigurationVariables() API 检查运行时使用的值

栈(Stack)

  • 栈内存是自动分配的。函数调用时,局部变量在栈上分配,函数结束后自动释放。栈内存通常很小,适合存放小的数据(如基本类型、指针)。
  • 内存分配方式是LIFO(后进先出),即最后放入的变量会最先释放。

GC回收的过程

垃圾回收器在执行回收时,会释放应用程序不再使用的对象的内存。 它通过检查应用程序的根来确定不再使用的对象。 每个应用程序都有一组根。 每个根或者引用托管堆中的对象,或者设置为空。 应用程序的根包含线程堆栈上的静态字段、局部变量和参数以及 CPU 寄存器。 垃圾回收器可以访问由实时 (JIT) 编译器和运行时维护的活动根的列表。 垃圾回收器对照此列表检查应用程序的根,并在此过程中创建一个图表,在其中包含所有可从这些根中访问的对象。

不在该图表中的对象将无法从应用程序的根中访问。 垃圾回收器会考虑无法访问的对象垃圾,并释放为它们分配的内存。 在回收中,垃圾回收器检查托管堆,查找无法访问对象所占据的地址空间块。 发现无法访问的对象时,它就使用内存复制功能来压缩内存中可以访问的对象,释放分配给不可访问对象的地址空间块。 在压缩了可访问对象的内存后,垃圾回收器就会做出必要的指针更正,以便应用程序的根指向新地址中的对象。 它还将托管堆指针定位至最后一个可访问对象之后。 请注意,只有在回收发现大量的无法访问的对象时,才会压缩内存。 如果托管堆中的所有对象均未被回收,则不需要压缩内存。

为了改进性能,运行时为单独堆中的大型对象分配内存。 垃圾回收器会自动释放大型对象的内存。 但是,为了避免移动内存中的大型对象,不会压缩此内存。

代数

垃圾回收主要在回收短生存期对象时发生。 为优化垃圾回收器的性能,将托管堆分为三代:第 0 代、第 1 代和第 2 代,因此它可以单独处理长生存期和短生存期对象。

第0代:

新分配的小对象构成新一代对象,并隐式地成为第 0 代集合,如果是大对象则为大型对象堆 (LOH),也称为第 3 代。

第1代:

如果第 0 代托管堆的回收没有回收足够的内存供应用程序创建新对象,垃圾回收器就会先执行第 1 代托管堆的回收,然后再执行第 2 代托管堆的回收。 第 1 级托管堆中未被回收的对象将会升级至第 2 级:

这一代包含长生存期对象。 长生存期对象的一个示例是服务器应用程序中的一个包含在进程期间处于活动状态的静态数据的对象。

第 2 代托管堆中未被回收的对象会继续保留在第 2 代托管堆中,直到在将来的回收中确定它们无法访问为止。 大对象堆也是在这一代进行会输

活动对象

垃圾回收器使用以下信息来确定对象是否为活动对象:

  • 堆栈根:由实时 (JIT) 编译器和堆栈查看器提供的堆栈变量。 JIT 优化可以延长或缩短报告给垃圾回收器的堆栈变量内的代码的区域。

  • 垃圾回收句柄:指向托管对象且可由用户代码或公共语言运行时分配的句柄。

静态数据:应用程序域中可能引用其他对象的静态对象。 每个应用程序域都会跟踪其静态对象

   在垃圾回收启动之前,除了触发垃圾回收的线程以外的所有托管线程均会挂起。所以频繁的垃圾回收会造成性能的损失。


http://www.ppmy.cn/server/120611.html

相关文章

TS React 项目中使用TypeScript

在 React 项目中使用 TS 创建新项目 在现有项目中添加 TS 创建新项目 命令:npx create-react-app my-app --template typescript 说明:在命令行中,添加 --template typescript 表示创建支持 TS 的项目 项目目录的变化: 在项目…

C语言:冒泡排序的注意事项及具体实现

一、注意事项 1、函数声明为:void bubble_sort(void* base, size_t num, size_t width, int (*cmp)(const void* e1, const void* e2)); 2、base 指向所要排序的数组 3、num 为数组的元素个数 4、width 为一个元素占多少个字节的空间 5、cmp 为函数指针,…

Java中stream流及Collectors的常见用法详细汇总!!!

目录 1. Stream流的优势 2. 常用用法 2.1 中间操作 2.1.1filter() 2.1.2 map() 2.1.3 sorted() 2.1.4 distinct() 2.1.5 limit() 2.1.6 skip() 2.2 终端操作 2.2.1 foreach() 2.2.2 collect() 2.2.3 reduce() 2.2.4 count() 2.2.5 anyMatch() 2.3 查找和匹配…

动态IP是如何实现的?

相信很多人都知道动态IP和静态IP的区别,但对于动态IP的实现过程或许还有些疑惑。那么接下来就为大家介绍一下动态IP的实现过程! 动态IP的实现离不开一个关键协议,那就是DHCP。DHCP协议的主要任务就是在网络中自动分配IP地址,让设…

使用cmd命令窗口操作mongodb

一、效果显示 二、下载MongoDB 1. 在官网下载安装MongoDB 官网网址:Download MongoDB Community Server | MongoDB 我安装的版本是7.0.14(注意安装到空闲磁盘) 三、启动MongoDB服务 1. 配置环境变量 注意替换为你的路径。 2. 在MongoDB的data下创建db文件夹 在…

运维工程师面试整理-操作系统

在运维工程师的面试中,操作系统相关的知识通常是重中之重,尤其是Linux/Unix系统。以下是针对操作系统部分的一些详细内容,帮助你更好地准备面试。 1. Linux/Unix 基础 ● 常用命令 ○ 文件和目录管理:ls, cd, cp, mv, rm, mkdir, rmdir, find, grep, awk, sed

CentOS入门宝典:从零到一构建你的Linux服务器帝国

目录 引言 一、CentOS简介与版本选择 1.1 CentOS是什么? 1.2 版本选择 二、安装CentOS 2.1 准备安装介质 2.2 安装过程 三、基础配置与优化 3.1 更新系统 3.2 配置防火墙 3.3 配置SELinux 3.4 系统监控与日志 四、网络配置与管理 4.1 配置静态IP 4.…

华南理工大学信息工程高频电子线路课程设计——基于锁相环的调试解调器设计

完整报告链接如下: 通过网盘分享的文件:高频课设报告.docx 链接: https://pan.baidu.com/s/1J83UCDSU0UHcv4ONYxfyhg?pwdzqyr 提取码: zqyr --来自百度网盘超级会员v5的分享 懒得贴上来了,放一下截图。