深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC,提搞程序性能

深入浅出图解C#堆与栈 C# Heaping VS Stacking 第六节 理解垃圾回收GC,提搞程序性能

  • [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)
  • [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理](https://mp.csdn.net/mdeditor/101022949#)
  • [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第三节 栈与堆,值类型与引用类型](https://mp.csdn.net/mdeditor/101023885#)
  • [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 1](https://mp.csdn.net/mdeditor/101026168#)
  • [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 2](https://mp.csdn.net/mdeditor/101027584#)
  • [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复](https://mp.csdn.net/mdeditor/101028008#)
  • [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC,提搞程序性能](https://mp.csdn.net/mdeditor/101029557#)
  • 理解垃圾回收GC,提搞程序性能
    • 前言
    • 简介
    • 绘图Graphing
    • GC垃圾清理Compacting
    • 托管堆之外的终止化队列Finalization Queue和终止化-可达队列Freachable Queue
    • 静态变量
    • 总结

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第三节 栈与堆,值类型与引用类型

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 1

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 2

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC,提搞程序性能

理解垃圾回收GC,提搞程序性能

前言

虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC),但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC)。另外,了解内存管理可以帮助我们理解在每一个程序中定义的每一个变量是怎样工作的。


简介

这一节我们将介绍垃圾回收机制GC以及一些提搞程序性能的技巧。


绘图Graphing

让我们站在GC的角度研究一下。如果我们负责“扔垃圾”,我们需要制定一个有效的“扔垃圾”计划。显然,我们需要判断哪些是垃圾,哪些不是。

为了决定哪些需要保留,我们假设任何没有正在被使用的东西都是垃圾(如角落里堆积的破旧纸张,阁楼里一箱箱没有用的过时产品,柜子里不用的衣服)。想像一下我们跟两个好朋友生活在一起:JIT 和CLR。JIT和CLR不断的跟踪他们正在使用的东西,并给我们一个他们需要保留的东西列表。这个初始列表我们叫它“根(root)”列表。因为我们用它做起点。我们将保持一个主列表去绘制一张图,图中分布着所有我们在房子中需要保留东西。任何与主列表中有关联的东西也被画入图中。如,我们保留电视就不要扔掉电视遥控器,所以电视遥控器也会被画入图中。我们保留电脑就不能扔掉显示器键盘鼠标,同样也把它们画入图中。

这就是GC怎么决定去保留对象的。GC会保留从JIT和CLR那收到的一个根(root)对象引用列表,然后递归搜索对象引用并决定什么需要保留。

这个根的构成如下:

  • 全局/静态 指针。通过以静态变量的方式保持对象的引用,来确保对象不会被GC回收。
  • 栈里的指针。为了程序的执行,我们不想扔掉那些程序线程始终需要的对象。
  • CPU寄存器指针。托管堆里任何被CPU内存地址指向的对象都需要被保留。

在这里插入图片描述
在上面的图中,托管堆中的对象1,5被根Roots引用,3被1引用。对象1,5是被直接引用,3是通过递归查询找到。如果关联到我们之前的假设,对象1是我们的电视,对象3则是电视遥控器。当所有对象画完后,我们开始进行下一阶段:垃圾清理。

GC垃圾清理Compacting

现在我们有了一张需要保留对象的关系图,接下来进行GC的清理。
在这里插入图片描述
图中对象2和4被认定为垃圾将被清理。清理对象2,复制(memcpy )对象3到2的位置。
在这里插入图片描述
由于对象3的地址变了,GC需要修复指针(红色箭头)。然后清理对象4,复制(memcpy )对象5到原来3的位置(译外话:GC原则:堆中对象之间是没有间隙的,以后会有文章专门介绍GC原理)。
在这里插入图片描述
在这里插入图片描述
最后清理完毕,新对象将被放到对象5的上面(译外话:GC对一直管理一个指针指向新对象将被放置的地址,如黄色箭头,以后会有文章专门介绍)。

了解GC原理可以帮助我们理解GC清理(复制memcpy ,指针修复等)是怎么消耗掉很多资源的。很明显,减少托管堆里对象的移动(复制memcpy )可以提高GC清理的效率。

托管堆之外的终止化队列Finalization Queue和终止化-可达队列Freachable Queue

有些情况下,GC需要执行特定代码去清理非托管资源,如文件操作,数据库连接,网络连接等。一种可行性方案是使用析构函数(终结器):
在这里插入图片描述
译外话:析构函数会被内部转换成终结器override Finializer()

有终结器的对象在创建时,同时在Finalization Queue里创建指向它们的指针(更正原文说的把对象放到Finalization Queue里):

在这里插入图片描述
上图对象1,4,5实现了终结器,因此在Finalization Queue里创建指向它们的指针。让我们看一下,当对象2和4没有被程序引用要被GC清理时会发生什么情况。
对象2会被以常规模式清理掉(见文章开始部分)。GC发现对象4有终结器,则会把Finalization Queue里指向它的指针移到Freachable Queue中,如下图:
在这里插入图片描述
但是对象4并不被清理掉。有一个专门处理Freachable Queue的线程,当它处理完对象4在Freachable Queue里的指针后,会把它移除。

在这里插入图片描述
这时对象4可以被清理了。当下次GC清理时会把它移除掉。换句话说,至少执行两次GC清理才能把对象4清理掉,显然会影响程序性能。

创建终结器,意味着创建了更多的工作给GC,也就会消耗更多资源影响程序性能。因此,当你使用终结器时一定要确保你确实需要使用它。
更好的方法是使用IDisposable接口。

在这里插入图片描述
实现IDisposable接口的对象可以使用using关键字:
在这里插入图片描述
变量rec的作用域是大括号内,大括号外不可访问。

静态变量

在这里插入图片描述

如果你初始化了TryoutRunners,那么它将永远不会被GC清理,因为有静态指针一直指向初始化的对象。一旦调用了Runner里GetStats()方法,因为GetStats()里面没有文件关闭操作,它将永远被打开也不会被GC清理。我们可以看到程序的崩溃即将来临。

总结

一些良好的操作可以提高程序的性能:

1.清理。不要打开资源而不关闭它。关闭所有你打开的连接。尽可能快的清理所有非托管资源。一般规则:使用非托管对象,初始化越晚越好,清理越早越好。
2.不要过度引用。合理使用引用对象。如果某一个对象还存在没有被GC清理,所有它引用的对象都将不会被GC清理,如此递归下去。。。当我们完成使用一个引用对象时,把它设为NULL(视你的情况而定,注意不要产生空引用异常)。当引用少了,GC开始创建清理关系图graphing时过程就简单一些了,进而提高程序性能。
3.谨慎使用终结器Finalizaer或析构函数。能使用IDisposible代替就使用IDisposible。
4.保持对象及其成员的紧凑。如果声明一个对象并且它由多个子对象组成,尽可能的把它们放在一起初始化,好让它们所在的内存空间紧凑。GC复制这样的一大块内存比复制分散的内存碎片要容易。

原文连接:https://blog.csdn.net/leewhoee/article/details/17109201
译文连接:http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory_401282006141834PM/csharp_memory_4.aspx

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

泛目录是干什么用的蚂蚁seo泛程序

泛目录是干什么用的蚂蚁seo泛程序目录 泛目录是一种常见的网站优化方法,属于黑帽技术的一种。它的核心原理是利用高权重的网站继承目录,然后快速获得收录与排名。这种方法可以帮助网站在搜索引擎中获得更好的排名,从而吸引更多的流量。 泛目…

右键菜单“以notepad++打开”,在windows文件管理器中

notepad 添加到文件管理器的右键菜单中 找到安装包,重新安装一般即可。 这里有最新版:地址 密码:f0f1 方法 在安装的时候勾选 “Context Menu Entry” 即可 Notepad的右击打开文件功能 默认已勾选 其作用是添加右键快捷键。即,对于任何…

云计算:OpenStack 配置云主机实例的资源实现内网互通

目录 一、实验 1. 环境 2.配置项目及用户 3.配置规格实例与镜像 4.配置VPC 5. 配置安全组 6. 创建云主机 cs_01 (cirros系统) 7.创建云主机 cs_02 (cirros系统) 8.创建云主机 cs_03 (cirros系统) …

小米路由器2(R2D) 安装 MIXBOX

1. 先刷开发版 ROM http://www1.miwifi.com/miwifi_download.html 进入上述网页,找到 R2D 点击下载 开发版 ROM 教程 看 下载按钮上边的 “刷机教程” 刷机教程 2. 开启SSH工具 登录自己的小米账号后,里面会显示出 自己的 root密码; 默认…

uniapp中的uview组件库丰富的Keyboard 键盘 用法

目录 基本使用 #隐藏键盘"."符号 #是否打乱按键的顺序 #如何控制键盘的打开和关闭? #如何监听键盘按键被点击? API #Props #Events #Slot 基本使用 通过mode参数定义键盘的类型,show绑定一个值为布尔值的变量控制键盘的弹…

每日一题:LeetCode-LCR 179. 查找总价格为目标值的两个商品

每日一题系列(day 16) 前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 &#x1f50e…

JVM 常用知识和面试题

1. 什么是JVM内存结构? jvm将虚拟机分为5大区域,程序计数器、虚拟机栈、本地方法栈、java堆、方法区; 程序计数器:线程私有的,是一块很小的内存空间,作为当前线程的行号指示器,用于记录当前虚拟…

InterSystems 数据库的存储过程存在哪里

我们都知道 InterSystems 的 Studio 可以创建存储过程。 但这个存储过程我们保存的时候是保存在哪里? 存储逻辑 如果我们在 Studio 创建存储过程的话,存储过程是存储在数据库上面的。 本地文件夹中是没有存储的。 选择系统下面的存储过程&#xff0c…

Keras多分类鸢尾花DEMO

完整的一个小demo: pandas1.2.4 numpy1.19.2 python3.9.2 import numpy as np import pandas as pd import matplotlib.pyplot as plt from pandas import DataFrame from scipy.io import loadmat from sklearn.model_selection import train_test_split impor…

Selenium库和ChromeDriver谷歌驱动最新版安装

1.安装selenium库 使用pip安装第三方库selenium,速度较慢。 pip install selenium 使用国内清华源安装第三方库selenium,速度较快。 pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple 2.安装谷歌浏览器驱动 驱动下载链接&#x…

GoogleNetv1:Going deeper with convolutions更深的卷积神经网络

文章目录 GoogleNetv1全文翻译论文结构摘要1 引言2 相关工作3 动机和高层考虑稀疏矩阵 4 结构细节引入1x1卷积核可以减少通道数 5 GoogleNet6 训练方法7 ILSVRC 2014 分类挑战赛设置和结果8 ILSVRC 2014检测挑战赛设置和结果9 总结 论文研究背景、成果及意义论文图表 GoogleNet…

iPhone 13 Pro 更换『移植电芯』和『超容电池』体验

文章目录 考虑换电池Ⅰ 方案一Ⅱ 方案二 总结危险 Note系列地址 简 述: 首发买的iPhone 13P &#xff08;2021.09&#xff09;&#xff0c;随性使用一年出头&#xff0c;容量就暴跌 85%&#xff0c;对比朋友一起买的同款&#xff0c;还是95%。这已经基本得一天两充 >_<&a…

代码随想录刷题笔记(DAY2)

今日总结&#xff1a;今天在学 vue 做项目&#xff0c;学校还有很多作业要完成&#xff0c;熬到现在写完了三道题&#xff0c;有点太晚了&#xff0c;最后一道题的题解明天早起补上。 Day 2 01. 有序数组的平方&#xff08;No. 977&#xff09; 给你一个按 非递减顺序 排序的…

搭建简单的GPT聊天机器人

目录 第一步 进行语料库读取、文本预处理&#xff0c;完成data_utls.py 第二步 进行Seq2Seq模型的构建&#xff0c;完成Seq2Seq.py 第三步 进行模型参数设置、加载词典和数据、数据准备、GPU设置、构建优化器和损失函数&#xff0c;进行模型的训练和测试&#xff0c;完成…

使用vue3实现echarts漏斗图表以及实现echarts全屏放大效果

1.首先安装echarts 安装命令&#xff1a;npm install echarts --save 2.页面引入 echarts import * as echarts from echarts; 3.代码 <template> <div id"main" :style"{ width: 400px, height: 500px }"></div> </template> …

OSPF被动接口配置-新版(14)

目录 整体拓扑 操作步骤 1.基本配置 1.1 配置R1的IP 1.2 配置R2的IP 1.4 配置R4的IP 1.5 配置R5的IP 1.6 配置PC-1的IP地址 1.7 配置PC-2的IP地址 1.8 配置PC-3的IP地址 1.9 配置PC-4的IP地址 1.10 检测R1与PC3连通性 1.11 检测R2与PC4连通性 1.12 检测R4与PC1连…

SuperMap iServer发布的ArcGIS REST 地图服务如何通过ArcGIS API进行要素查询

作者&#xff1a;yx 前言 前面我们介绍了SuperMap iServer发布的ArcGIS REST 地图服务如何通过ArcGIS API加载&#xff0c;这里呢我们再来看看如何进行要素查询呢&#xff1f; 一、服务发布 SuperMap iServer发布的ArcGIS REST 地图服务如何通过ArcGIS API加载已经介绍如何发…

【Vue3】创建项目的方式

1. 基于 vue-cli 创建 ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version## 安装或者升级你的vue/cli npm install -g vue/cli## 执行创建命令 vue create vue_test本质上使用webpack&#xff0c;默认安装以下依赖&#xff1a; 2. 基于 vite 创建 官…

mac 生成 本地.ssh

输入下面命令行 ssh-keygen 默认回车得到下面的 Generating public/private rsa key pair. Enter file in which to save the key (/Users/{用户名}/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has be…

深入浅出理解转置卷积Conv2DTranspose

一、参考资料 【keras/Tensorflow/pytorch】Conv2D和Conv2DTranspose详解 怎样通俗易懂地解释反卷积&#xff1f; 转置卷积&#xff08;Transposed Convolution&#xff09; 抽丝剥茧&#xff0c;带你理解转置卷积&#xff08;反卷积&#xff09; 二、标准卷积(Conv2D) 1. Co…
最新文章