垃圾回收 (GC) 在 .NET Core 中是如何工作的?(二)

接上一篇文章垃圾回收 (GC) 在 .NET Core 中是如何工作的?-CSDN博客

GC 会分配堆段,其中每个段都是一系列连续的内存。 置于堆中的对象归类为 3 个代系之一:0、1 或 2。 代系可确定 GC 尝试在应用不再引用的托管对象上释放内存的频率。 编号较低的代系会更加频繁地进行 GC。

对象会基于其生存期从一个代系移到另一个代系。 随着对象生存期延长,它们会移到较高代系。 如前所述,较高代系进行 GC 的频率较低。 短期生存的对象始终保留在第 0 代中。 例如,在 Web 请求存在期间引用的对象的生存期较短。 应用程序级别单一实例通常会迁移到第 2 代。

当 ASP.NET Core 应用启动时,GC 会:

为初始堆段保留一些内存。
在运行时加载时提交一小部分内存。

HttpClient

未正确使用 HttpClient 可能会导致资源泄漏。 系统资源(如数据库连接、套接字、文件句柄等):

  • 比内存更短缺。
  • 在泄漏时出现的问题比内存更多。

经验丰富的 .NET 开发人员会对实现 IDisposable 的对象调用 Dispose。 未释放实现 IDisposable 的对象通常会导致内存泄漏或系统资源泄漏。

HttpClient 实现了 IDisposable,但是不应在每次调用时进行释放。 而是应重用 HttpClient

下面的api会对每个请求创建并释放新的 HttpClient 实例:

[HttpGet("httpclient1")]
public async Task<int> GetHttpClient1(string url)
{using (var httpClient = new HttpClient()){var result = await httpClient.GetAsync(url);return (int)result.StatusCode;}
}

上面的代码即使释放了 HttpClient 实例,实际网络连接也需要一些时间才能由操作系统释放。 持续创建新连接时,会发生端口耗尽。 每个客户端连接都需要自己的客户端端口。

防止端口耗尽的一种方法是重用同一个 HttpClient 实例:

private static readonly HttpClient _httpClient = new HttpClient();[HttpGet("httpclient2")]
public async Task<int> GetHttpClient2(string url)
{var result = await _httpClient.GetAsync(url);return (int)result.StatusCode;
}

HttpClient 实例会在应用停止时释放。 

可以参阅以下内容,了解处理 HttpClient 实例的生存期:

  • HttpClient 和生存期管理
  • HTTPClient 工厂博客

对象池

上面的示例演示了如何将 HttpClient 实例设为静态,并由所有请求重用。 重用可防止资源耗尽。

对象池:

  • 使用重用模式。
  • 适用于创建成本高昂的对象。

池是预初始化对象的集合,这些对象可以在线程间保留和释放。 池可以定义分配规则,例如限制、预定义大小或增长速率。

下面的 API 会实例化 byte 缓冲区,该缓冲区对每个请求使用随机数字进行填充:

[HttpGet("array/{size}")]public byte[] GetArray(int size){var random = new Random();var array = new byte[size];random.NextBytes(array);return array;}

可以使用 ArrayPool<T> 创建 byte 缓冲区池,从而优化上面的代码。 静态实例可在请求间重用。

此方法的不同之处在于,会从 API 返回共用对象。 也就是说:

  • 从方法返回后,对象会立即脱离控制。
  • 无法释放对象。

若要设置对象的释放,请执行以下操作:

  • 将共用数组封装在可释放对象中。
  • 向 HttpContext.Response.RegisterForDispose 注册共用对象。

RegisterForDispose 会负责对目标对象调用 Dispose,以便仅当 HTTP 请求完成时才会将其释放

private static ArrayPool<byte> _arrayPool = ArrayPool<byte>.Create();private class PooledArray : IDisposable
{public byte[] Array { get; private set; }public PooledArray(int size){Array = _arrayPool.Rent(size);}public void Dispose(){_arrayPool.Return(Array);}
}[HttpGet("pooledarray/{size}")]
public byte[] GetPooledArray(int size)
{var pooledArray = new PooledArray(size);var random = new Random();random.NextBytes(pooledArray.Array);HttpContext.Response.RegisterForDispose(pooledArray);return pooledArray.Array;
}

主要差异是分配的字节数,因而第 0 代回收数要少得多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/224043.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【亚马逊云科技】使用Vscode Amazon-Q完成GUI界面粉笔脚本开发

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 前言 亚马逊云科技-Q&#xff0c;可以快速获得紧迫问题的相关答案&#xff0c;解决问题…

生物信息学分析领域领先的特制语言环境NGLess(Next Generation Less)介绍、安装配置和详细使用方法

介绍 NGLess&#xff08;Next Generation Less&#xff09;是一种用于生物信息学分析的领先的领域特定语言&#xff08;DSL&#xff09;。它旨在简化和加速NGS&#xff08;Next Generation Sequencing&#xff09;数据的分析过程。NGLess具有清晰的语法和功能&#xff0c;使用户…

机器翻译:跨越语言边界的智能大使

导言 机器翻译作为人工智能领域的瑰宝&#xff0c;正在以前所未有的速度和精度&#xff0c;为全球沟通拓展新的可能性。本文将深入研究机器翻译的技术原理、应用场景以及对语言交流未来的影响。 1. 简介 机器翻译是一项致力于通过计算机自动将一种语言的文本翻译成另一种语言的…

[Unity]关于Unity接入Appsflyer并且打点支付

首先需要去官方下载Appsflyer的UnityPackage 链接在这afPackage 然后导入 导入完成 引入此段代码 using AppsFlyerSDK; using System.Collections; using System.Collections.Generic; using UnityEngine;public class AppflysManager : MonoBehaviour {public static App…

测试总监给我分享的《接口自动化测试》总结,让我成功的入门接口自动化门槛......

前两天在测试技术交流群里&#xff0c;听了一位字节跳动的测试总监分享的接口自动化测试的内容&#xff0c;对接口自动化更加了解了&#xff0c;也为自己接下来在公司实施接口自动化项目提供了思路。 前言 自动化测试&#xff0c;算是近几年比较火热的一个话题&#xff0c;当…

现代C++ 实现单例模式

传统写法有什么问题 如果你了解过单例模式&#xff0c;双重检查锁定模式&#xff08;Double-Checked Locking Pattern&#xff0c;后文简称DCLP&#xff09;的写法你一定不会陌生&#xff0c;甚至你或许认为它是最正确的代码。 class Singleton { public://获取单例Singleton…

解决:Component name “index“ should always be multi-word

原因 要求组件名称以驼峰格式命名&#xff0c;自定义组件名称应该由多单纯组成&#xff0c;防止和html标签冲突&#xff0c;所以index.vue 会报错 解决 1、按照规则驼峰格式&#xff0c;如&#xff1a;appIndex.vue 2、若有.eslintrc.js文件&#xff0c;并在规则中(rules)关…

数据挖掘-08-基于Python实现时间序列分析建模(ARIMA 模型)(包括数据和代码)

文章目录 0. 数据代码下载1. 背景描述2. 预测目的3. 数据总览4. 数据预处理4.1数据描述性统计与清洗a. 导入程序库b. 读取数据c. 查看统计信息和空值d. 查看是否有重复数据以及清理重复数据e. 空值清理f. 针对清洗后的数据进行统计分析 5. 探索性数据分析5.1 数据分析 6. 构建 …

猫粮哪个牌子质量好性价比高?盘点十款主食冻干猫粮品牌排行榜!

在过去的100多年里&#xff0c;猫咪主食市场一直被膨化猫粮主导。然而&#xff0c;随着猫咪频频出现猝死、失明、发育不良以及营养不良等问题&#xff0c;猫主人们开始质疑膨化粮是否最适合猫咪。于是&#xff0c;从上世纪90年代开始&#xff0c;出现了生骨肉喂养。生骨肉确实是…

网络安全——基于Snort的入侵检测实验

一、实验目的要求&#xff1a; 二、实验设备与环境&#xff1a; 三、实验原理&#xff1a; 四、实验步骤&#xff1a; 五、实验现象、结果记录及整理&#xff1a; 六、分析讨论与思考题解答&#xff1a; 七、实验截图&#xff1a; 一、实验目的要求&#xff1a; 1、掌握…

一、win10+yolov8+anaconda环境部署

1、安装anaconda &#xff08;1&#xff09;打开aonconda下载地址&#xff1a;https://www.anaconda.com/download&#xff0c;点击download下载。 2、下载完成后&#xff0c;双击打开&#xff0c;点击Next&#xff0c;I Agree&#xff0c;选择just me&#xff1b; 3、勾选…

Spring上下文之注解模块ConfigurationMethod

博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…

飞天使-docker知识点8-docker的资源限制

文章目录 容器资源限制示例 容器资源限制 Docker提供了多种资源限制的方式&#xff0c;可以根据应用程序的需求和系统资源的可用性进行选择。以下是一些常见的Docker资源限制及其使用情况&#xff1a;CPU限制&#xff1a;通过设置CPU的配额&#xff08;quota&#xff09;和周期…

网络(九)CanSM及达芬奇配置

【小猫爪】AUTOSAR学习笔记05-Communication Stack之CanSM模块-CSDN博客 上链接讲的非常好。 CanSM提供的函数。 C CanSM使用的函数&#xff1a;

spring mail 邮件发送demo

首先配置号邮件服务器&#xff08;我用的是126邮箱&#xff09;&#xff0c;获取密钥&#xff1a; 进入下图的【邮箱中心】->点击右侧的齿轮按钮 接着&#xff0c;开启 下图位置 的 POP3/SMTP&#xff08;我当时点击开启时&#xff0c;需要手机扫码认证下&#xff09; 最后…

putIfAbsent、computeIfAbsent、computeIfPresent

putIfAbsent 判断是否存在&#xff0c;不存在则设置 hashmap.putIfAbsent(K key, V value) 例子如下&#xff1a; public static void main(String[] args) {//hashmap.putIfAbsent(K key, V value)HashMap hashMap Maps.newHashMap();hashMap.put("aa","on…

ConnectionError怎么解决

文章目录 解决思路lz的具体解决过程 解决思路 这个错误表明在尝试加载评价指标时&#xff0c;代码试图从 huggingface 下载文件&#xff0c;但由于代理错误而无法连接。 为了解决这个问题&#xff0c;你可以尝试以下几个步骤&#xff1a; 1.设置代理&#xff1a; 如果你在使…

Zabbix监控系统部署与管理

zabbix介绍 zabbix是⼀个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的免费开源解决⽅案。zabbix能监视各种⽹络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 zabbix构成 zabbix由…

Windows进程机制

进程 进程要做任何事情&#xff0c;必须让一个线程在它的上下文运行。该线程负责执行进程地址空间包含的代码。每个进程至少要有一个线程来执行进程地址空间包含的代码。当系统创建一个进程的时候&#xff0c;会自动为进程创建第一个线程&#xff0c;这称为主线程&#xff08;…

命令调用先构建hashTable

GPT 代码改 #include <stdio.h> #include <stdlib.h> #include <string.h>#define TABLE_SIZE 256struct Node {char *key;void *value;struct Node *next; };struct HashTable {struct Node *table[TABLE_SIZE]; };void initHashTable(struct HashTable *ha…