Task.Run为什么会存在内存泄漏的风险?

由于值类型是拷贝方式的赋值,捕获的本地变量和类成员是指向各自的值,对本地变量的捕获不会影响到整个类。但如果把类中的值类型改为引用类型,那这两者最终指向的是同一个对象值,这是否意味着使用本地变量还是无法避免内存泄漏?

GC在第一次回收时,发现某实例还存在被捕获成员,则认为它不应该被回收。假如这个实例对象中存在Task.Run,当Task.Run执行完毕后,GC不就可以回收这个实例了吗?

public class TaskClass{private int _id;private List<string> _list;public Task Test(){var LocalID = _id;return Task.Run(() =>{Console.WriteLine("Task.Run is executing with ID={0}", LocalID);Thread.Sleep(1500);});}}

我们先把变量_id的值类型改为引用类型string,运行的结果是和int类型一致,这说明和值类型或引用类型无关。

我们知道,在创建引用类型时会在栈上开辟内存空间,在该地址存储该变量的名称,用于对地址的引用,该变量对应的值存储在托管堆中。局部变量Local ID和类成员_id,在栈中有不同的地址,栈中所指向到托管堆中的地址也是不同,但是托管堆地址中对应的值是相同的。

所谓被捕获就是被作用域捕获,当作用域结束时,该作用域内成员的地址空间也会被释放,至于地址指向的托管堆中的字符串,则不是作用域该关心的事情。当字符串值对应的地址空间没有变量指向时,就会被GC回收。

当CLR尝试搜索不再使用的对象时,它需要遍历托管堆上的对象。随着程序的不断运行,托管堆可能会不断变大,如果GC对整个托管堆回收,势必会造成对程序性能的影响,甚至崩贵。所以,为了优化这个过程,微软在CLR中使用了分带算法。

分带算法就是把内存中的资源划分为三代,分别是Gen 0、Gen 1、Gen 2,GC遍历它们的频率由高到低。新创建对象的会被标记为Gen 0,GC扫描它们的频率最高;当GC进行一次扫描后,未被回收的对象会被标记为Gen 1;当GC扫描被标记为Gen 1的对象时,未被回收的对象被标记为Gen 2,Gen 2的回收被称为Full GC,只有在满足一定条件时才会执行。资源在内存中停留的时间越长,越不容易被回收。

在这里插入图片描述

当对象进入Gen 2时,没有一定的触发条件,资源是不会被回收的。

当我们理解分带算法后,上面那段代码相应的三个时间点:1、作用域的结束时间点;2、GC回收的时间点;3、Task.Run执行的结束点。

如果程序的执行顺序是1、3、2,那么就不会存在内存泄漏问题。但实际情况是,Task.Run一般是执行耗时操作,非耗时任务一般是不会使用Task.Run。所以程序执行的时间顺序可能是1、2、3,当GC回收该对象时,由于该对象的作用域还未被释放,GC会将该对象标记为Gen 1。如果Task.Run执行的时间够长,该对象会被标记为Gen 2,若没有相应的触发条件,该对象永远都不会被回收。

在大部分场景中,我们还是可以放心的去使用Task.Run。如果Task.Run中的局部变量捕获了类中的成员,使该对象进入Gen 2,Gen 2中未被释放的资源也是有限的,不可能是无限增加。当Gen 2中的资源累积到一定程度时,就会触发相应的条件,GC会将Gen 2中未被使用的资源释放。当然,我们还是要尽可能避免在Task.Run匿名类中捕获类成员。

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

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

相关文章

【java】-D参数使用

在开发过程中我们使用开源工具经常会用到在启动命令时候加入一个 -Dxxx 类型的参数。到底-Dxxx是干什么用的了。 官方文档 地址&#xff1a;文档地址 java命令使用 下面是来源于官方文档&#xff1a; java [options] classname [args] java [options] -jar filename [args…

FFmpeg零基础学习(二)——视频文件信息获取

目录 前言正文一、获取宽高信息1、核心代码2、AVFormatContext3、avformat_alloc_context4、avformat_open_input5、avformat_find_stream_info6、av_dump_format7、av_find_best_stream End、遇到的问题1、Qt Debug模式avformat_alloc_context 无法分配对象&#xff0c;而Rele…

2023年汉字小达人市级比赛在线模拟题的使用顺序、建议和常见问题

今天是2023年11月25日&#xff0c;星期六&#xff0c;上午举办了2023年第八届上海小学生古诗文大会的复选活动&#xff08;复赛&#xff09;&#xff0c;结束了复选活动&#xff0c;很多学霸孩子们马上就开始投入到第十届汉字小达人的市级活动&#xff08;市级比赛&#xff09;…

PCL 计算两点云之间的最小距离

目录 一、 算法原理二、 代码实现三、 结果展示四、 相关链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、 算法原理 pcl::registration::CorrespondenceEstimation是确定目标和查询点集(或特征)之间对应关…

【Web】CmsEasy 漏洞复现

访问主页 到处点一点没啥发现 扫目录 访问/admin 账号密码都是admin admin,不知道为什么&#xff0c;这里就先当作是默认吧 &#xff08;其实都是信息检索&#xff0c;能在网上搜到就行hhh&#xff09; 登录成功 看到左边列表有模板&#xff0c;心里大概有数了哈 进行一波历…

Android虚拟化

一、开源项目 开源的项目有一些&#xff0c;比如完全虚拟化的&#xff1a; twoyi 两仪由两部分组成&#xff1a;两仪 App&#xff0c;它实际上是一个 UI 渲染引擎&#xff0c;两仪内部运行的 ROM。 但是看telegram和github&#xff0c;这个app没有完整开源&#xff0c;并且最近…

二维列表如何利用set()进行去重

一维列表去重 输入&#xff1a; a[1,2,3,4,5,6,6] print(a) print(type(a)) bset(a) print(b) 输出&#xff1a; [1, 2, 3, 4, 5, 6, 6] <class list> {1, 2, 3, 4, 5, 6} 代码显示一维列表去重是没有问题的 二维列表去重 输入&#xff1a; a[[1,2,3,],[4,5,6],[…

StarRocks Evolution:One Data,All Analytics

在 11 月 17 日举行的 StarRocks Summit 2023上&#xff0c;StarRocks TSC Member、镜舟科技 CTO 张友东详细介绍了 StarRocks 社区的发展情况&#xff0c;并全面解析了 StarRocks 的核心技术与未来规划&#xff1b;我们特意将他的精彩演讲整理出来&#xff0c;以帮助大家更深入…

Typescript的数据类型

Typescript Typescript 是 Javascript 的一个超集。 Typescript 在原有 js 的基础之上又添加了编译期的类型检查的功能。意味着如 果在ts 的环境下开发时&#xff0c;会对变量的数据类型进行较为严格的验证&#xff0c;防止程序员写出可能出问题的代码&#xff0c;规范编程习惯…

docker环境安装

环境 主机环境 1. 宿主机环境 ubuntu-22.04.3-live-server-amd64 &#xff0c;下载地址&#xff1a; https://mirrors.aliyun.com/ubuntu-releases/22.04.3/ubuntu-22.04.3-live-server-amd64.iso 2. apt 包管理器&#xff0c;镜像源修改 : 将 http://cn.archive.ubunt…

间接法加窗分析信号的功率谱

本篇文章是博主在通信等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对通信等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在 通信领域笔记&#xff…

【算法萌新闯力扣】:卡牌分组

力扣热题&#xff1a;卡牌分组 一、开篇 今天是备战蓝桥杯的第22天。这道题触及到我好几个知识盲区&#xff0c;以前欠下的债这道题一并补齐&#xff0c;哈希表的遍历、最大公约数与最小公倍数&#xff0c;如果你还没掌握&#xff0c;这道题练起来&#xff01; 二、题目链接:…

Redis key 过期监听实现

1.技术背景&#xff0c;想知道 redis 设置了TTL时间的key 过期&#xff0c;且有后续的业务处理的场景可以使用。 bug点&#xff1a; 使用redis 缓存失效监听会有一定的延迟&#xff0c; 过期事件是在redis服务器删除键的时候生成的&#xff0c;而不是在理论上生存时间到达0值得…

python每日一题——6三数之和

题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 …

【数据结构】树与二叉树(廿三):树和森林的遍历——层次遍历(LevelOrder)

文章目录 5.3.1 树的存储结构5. 左儿子右兄弟链接结构 5.3.2 获取结点的算法5.3.3 树和森林的遍历1. 先根遍历&#xff08;递归、非递归&#xff09;2. 后根遍历&#xff08;递归、非递归&#xff09;3. 森林的遍历4. 层次遍历a. 算法LevelOrderb. 算法解读c. 时间复杂度d.代码…

STM32 启动文件分析

STM32 启动文件分析 基于STM32F103VET6芯片的 startup_stm32f10x_hd.s 启动文件分析 设置栈&#xff0c;将栈的大小Stack_Size设置为0x00004900&#xff08;18688/102418KB&#xff09;&#xff0c;即局部变量不能大于18KB。&#xff08;EQU等值指令&#xff0c;将0x0000490…

Arduio开发STM32所面临的风险

据说micro_ros用到了arduino,然后用arduino搞stm32需要用到这个Arduino STM32的东西&#xff0c;然后这里申明了&#xff1a;这些代码没有经过严格测试&#xff0c;如果是向心脏起搏器&#xff0c;自动驾驶这样要求严格的的情况下&#xff0c;这个东西不能保证100%不发生问题&a…

尺度为什么是sigma?

我们先看中值滤波和均值滤波。 以前&#xff0c;我认为是一样的&#xff0c;没有区分过。 他们说&#xff0c;均值滤波有使图像模糊的效果。 中值滤波有使图像去椒盐的效果。为什么不同呢&#xff1f;试了一下&#xff0c;果然不同&#xff0c;然后追踪了一下定义。 12345&…

一体化污水处理设备各种材质的优缺点

一体化污水处理设备的材质有多种&#xff0c;包括不锈钢、玻璃钢、聚乙烯塑料、碳钢等。每种材质都有其独特的优点和缺点。 不锈钢材质的优点是防腐性能好&#xff0c;耐磨损&#xff0c;使用寿命长&#xff0c;且外观美观。其缺点是成本较高&#xff0c;不适合在一些特殊的环…

ESP32 ESP-IDF5.1 在Visual Studio Code中自定义分区表与调整Flash大小

好记心不如烂笔头 使用ESP-IDF开发ESP32的时候,要是同时用到蓝牙和WIFI的话,很多时候会提示Flash不够, 我是照着这样解决的,存档记录 来源 : zaixingxing2539 大佬的 ESP32 ESP-IDF5.0 在VSCODE中自定义分区表 用Visual Studio Code自定义分区表 # ESP-IDF Partition Table…