dotnet学习笔记五 - 无用资源回收之二

DotNet下使用GDI+绘图时资源是否需要释放 DotNet下使用GDI+绘图时资源是否需要释放 可能很少有人注意到这样的问题,最近我在写一个绘图模块的时候,忽然意识到这好象是一个问题,因为不过我们以前用GDI绘图时,书本的代码会明确地告诉你一定要删除自已创建的绘图对象,因此我们常常写完了SelectObject,一定会马上写一个DeleteObject,以防止资源泄漏。可是,当你来到的DotNet的环境下,你随便打开一本关于绘图的 阅读详情

l         Finalize

在上一篇文章中我分配使用资源一共五步,我们已经知道了GC是如何释放无用对象的内存了。但是它怎么实现第四步清空资源使用状态、释放利用到的一些非内存的系统资源呢?.NET引入了Finalize来完成这个任务。

GC在无用单元回收时一旦发现某个对象有Finalize方法,便调用它。所以我们的Finalize方法一定要尽量少做事情,以提高内存回收的速度。另外,在Finalize方法中不要有任何的线程同步等操作,以防止GC线程被挂起。

我们可以用两种方法来写自己的Finalize方法。一种就是显示的实现,如下面的代码:

代码1

public class SomeClass

{

   public SomeClass()

   {

   }

 

   protected override void Finalize()

   {

      Console.WriteLine(“Finalizing…”);

   }

}

使用这种方法时要注意一点,.NET不会帮你做调用基类的Finalize方法。如果需要调用基类的Finalize方法,需要显示的调用。如下面代码:

代码2

public class SomeClass

{

   public SomeClass()

   {

   }

 

   protected override void Finalize()

   {

      Console.WriteLine(“Finalizing…”);

      base.Finalize(); // 调用基类Finalize方法

   }

}

另外一种方法就是析构函数。C#中的析构函数不同于C++。我们看下面的代码:

代码3

public class SomeClass

{

   public SomeClass()

   {

   }

 

   ~SomeClass()

   {

      Console.WriteLine(“Finalizing…”);

   }

}

它等同于代码2。

使用Finalize方法要特别小心。因为使用Finalize方法的对象要比普通的对象花时间;GC也要花更多的时间来回收。而且CLR并不能保证调用Finalize的顺序,所以如果对象间有关联(比如一个成员变量先被Finalize了,如果在Finalize方法里还使用它,就会出错),就会更麻烦。

GC是如何实现Finalize的呢?GC维护了两个队列,Finalization队列和Freachable队列。在托管堆分配对象的时候,GC如果发现这个对象实现了一个Finalize方法,就把它加到Finalization队列。如图:

当托管堆的内存不足的时候,GC开始对堆进行回收。GC回收一个对象前,先检查Finalization队列中是否有这个对象的指针,如果有,就将其放入Freachable队列。Freachable队列被认为是根(root)的一部分,所以GC不会对其作回收。GC第一次回收后,堆如下图:

对象G和对象E不在根的范围之内,被回收。对象F和对象C由于需要Finalize被放入到Freachable队列,这个队列被认为是根的一部分,所以这是对象F和对象C就复活了,没有被GC回收。Freachable队列中的对象的Finalize方法被一个特殊的线程执行。这个线程平时处于非活动状态,一旦Freachable队列不再为空,它就醒过来,一一执行这个队列中对象中的Finalize方法。执行过后如下图:

这时对象F和对象C不再是根的一部分,如果此时GC进行回收,将会被认作无用对象进行回收,回收后如下图:

上面简单描述了Finalize作用及其内部的工作原理。下面来说一下Generation。

l         Generation

每次都对整个对进行搜索,压缩是非常耗时的。微软总结了一些过去的开发中出现的现象,其中有一条就是,越是新的对象,越是最快被丢弃不再使用。微软根据这个经验在内存回收中引入了Generation的概念,我此处暂时将其翻译成代。托管堆开始的时候是空的,程序启动开始在其中分配对象,这时候的对象就是第0代(Generation 0)对象。如下图:

接下来,到托管堆空间不足,GC进行了第一次回收,剩下的没有被回收的对象就升为第一代,之后再新分配的对象就是第0代(图甲)。再之后GC再进行回收的话只回收第0代,未被回收的第0代升级为第一代,原来的第一代升级为第0代(图乙)。

GC缺省的代(Generation)最高就是2,升级到第二代就不会再升级了。那什么时候GC回收第一,第二代呢?当GC回收完第0代后,发现内存空间还不够,就会回收第一代,回收完第一代,还不够,就回收第二代。

这一篇也写了不少了,所以下一篇再继续,下一篇写WeakReference和如何在自己的代码中控制GC的动作。

Dotnet程序中的内存管理和垃圾回收 Dotnet程序中的内存管理和垃圾回收是确保程序性能和稳定性的关键因素。同时,Dotnet的垃圾回收器提供了自动管理内存的机制,我们可以依赖它来释放不再使用的对象和内存资源。Dotnet的垃圾回收器使用了分代回收的策略。在编写和运行Dotnet程序时,我们需要有效地管理内存资源,以确保程序的性能和稳定性。需要注意的是,垃圾回收是一个自动的过程,我们一般不需要手动干预或主动触发垃圾回收。在编写Dotnet程序时,我们应该遵循一些内存管理的最佳实践,并进行代码审查和性能测试,以确保程序的内存使用是可控的。 阅读详情

相关推荐

STC8H开发(十六): GPIO模拟SPI驱动Ci24R1实现低成本无线遥控

本文详细介绍了如何使用STC8H单片机通过GPIO模拟SPI驱动Ci24R1无线模块,实现低成本无线遥控方案。内容涵盖硬件设计要点、软件驱动开发技巧及实战优化经验,特别适合消费电子产品开发者参考。Ci24R1凭借其高性价比和双模协议支持,成为替代传统nRF24L01+的理想选择。

weixin_30378623的博客 350

.NET中的垃圾回收原理全解

.NET中的垃圾回收(Garbage Collection)是一种自动内存管理机制,它负责在程序运行时自动回收不再使用的内存对象,以减轻开发人员的内存管理负担。以下是.NET垃圾回收的原理解析:垃圾收集器(Garbage Collector,简称GC):.NET Framework提供了一个垃圾收集器,它负责扫描和标记不再被引用的对象,并释放它们占用的内存。垃圾收集器是一个后台线程,周期性地运行。...

dotNET跨平台 612

Ubuntu 24.04下Loki+Alloy+Grafana日志分析系统的快速部署与实践

本文详细介绍了在Ubuntu 24.04系统上快速部署Loki+Alloy+Grafana轻量级日志分析系统的完整流程。通过二进制安装Loki、配置Alloy采集器以及设置Grafana可视化界面,构建了一套资源消耗低、易于管理的日志解决方案,并实战演示了如何采集和分析网络设备日志,特别适合资源有限的中小团队或边缘计算场景。

tensor9flow的博客 236

.NET 之 垃圾回收机制GC

.net GC

u012149999的博客 2112

UR机械臂正逆运动学解析:从DH参数到8组解的完整求解策略

本文深入解析UR机械臂的正逆运动学求解策略,从DH参数原理到完整的8组解求解方法。详细介绍了正运动学的坐标变换过程,以及逆运动学中Atan2函数和三角恒等变换的应用,并揭示了8组解的产生机制。通过实际案例和调试技巧,帮助工程师掌握UR机械臂运动学求解的核心技术。

weixin_29094775的博客 414

语义通信理论必看论文:Towards a Theory of Semantic Communication

了解语义通信发展必看的一篇文章

一去不复返的通信er 3927

浅谈.NET非托管资源垃圾回收与程序资源优化(弱引用)

程序的资源分为托管资源与非托管资源,CLR直接管理的资源就是托管资源,还有一类非托管资源如IO、Socket、AplicationContext、Regex、Stream流、数据库操作等等,这些直接由系统管理占用内存。在垃圾回收的时候,虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。      上一篇文章说了托管资源与垃圾回收,下面说说非托管资源垃圾回收: 我

xiaoyiyz的专栏 790

FPGA实现AXI-Stream通信

本文介绍了在FPGA中实现AXI-Stream接口的工业级方案,重点解析了核心协议信号(TVALID/TREADY/TDATA/TLAST)与可选扩展信号,并提供了Verilog最小化实现示例。文章详细阐述了握手协议规则、时序约束方法,以及吞吐量优化技巧(如寄存器切片和双缓冲策略),同时给出了跨时钟域处理的异步FIFO解决方案。此外,还包含验证调试方法(Testbench结构和ILA触发设置)和典型应用场景(视频处理/网络传输),最后提供了资源消耗参考数据。该实现方案严格遵循Xilinx/Intel官方规范

whm128的博客 1465

浅谈.NET垃圾回收

本篇博客简单地从以下几个方面讨论一下.net的垃圾回收(GC)问题 何时进行垃圾回收 回收哪些对象 回收过程和回收算法 编程建议 何时进行垃圾回收 一般情况下,.net在创建对象时发现托管堆的内存不够用了,就会进行垃圾回收。除此之外,手动调用GCCollect()方法时也会进行回收,还有就是当windows报告低内存时以及应用程序关闭时,也都会进行垃圾回收。 当.net clr试图创建

朱登凯的专栏 1760

使用 Python 爬虫获取中国证券市场公司公告数据

本文详细介绍了如何使用 Python 爬虫技术从中国证券市场(如巨潮资讯网)爬取公司公告数据。通过分析网页结构,编写爬虫脚本,抓取并存储公告信息,我们实现了从网页抓取数据的全过程。此外,本文还展示了如何应对反爬虫机制,并介绍了数据分析与可视化的基本方法。未来,我们可以通过机器学习等技术进一步挖掘公告中的潜在信息,例如,通过情感分析对公告内容进行情绪分类,或者预测某些公告类型对股市走势的影响等。希望本文能帮助你理解如何使用 Python 爬虫技术获取和处理证券市场的数据,并为你的数据分析项目提供帮助。

2201_76125261的博客 1887

华为OD机试真题 新系统 2026-05-13 Python&JS语言 实现【查找能被整除的最大整数】

给定一个字符串和一个正整数,字符串由大小写字母和数字组成,要求从字符串中找出最大且能被给定正整数整除的数。

MISAYAONE的博客 226

如何理解.net中的垃圾回收机制

.NET Framework 的垃圾回收器管理应用程序的内存分配和释放。每次您使用 new 运算符创建对象时,运行库都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃 圾回收器必须执行回收以释放一些内存。垃圾回收器优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被 应用程序...

weixin_33878457的博客 1715

ShaderJoy —— 简单又神奇的 “合体” 函数【GLSL】

smin 函数 它实际上有两种常见的实现方式 多项式 指数 多项式 smin 函数图 其对应的代码为 float smin( float a, float b ) { // 多项式 const float k = 0.5; float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0); return mix(b, a, h) - k * h * (1.0 - h); } 从上图中我们可以很明显的看出有两处不连...

ShaderJoy 的兴趣技术杂货铺 1858

dotnet学习笔记四 - 无用单元回收

我们平常写程序很少自己去写资源管理的,除非写非常大型的应用程序,或者大公司自己的sdk。看到过PGP源代码的一定知道,PGP的SDK就实现了自己的内存管理。自己管理内存烦恼实在多多,忘记释放了,释放了又再次访问的bug层出不穷,这种bug又非常难查。普通的逻辑bug,简单测试发现程序没有按照预想的运行就可以找到。但是内存的问题却很难发现。过去很多公司也为解决这方面的问题作过很大努力,比如Compu

kenli的专栏 2215

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

dotnet学习笔记六 - 无用资源回收之三

这篇文章接着上一次的来,继续讨论无用资源回收的其它一些话题。l         WeakReference(弱引用)我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现。弱引用使用起来很简单,看下面的代码:代码1Objec

kenli的专栏 1959

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

DotNet 网上资源

相关网站列表http://blog.joycode.com/ 博客堂 主要是微软专家的帖子,内容较新http://www.cnblogs.com/ 博客园http://www.microsoft.com/resources/practices/default.mspx 模式和实践首页http://msdn.microsoft.com/smartclient/ 智能客户端首页http://msdn.

Hacken的专栏 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Dotnet的垃圾回收

最近在做一个项目,用到了大量的非托管技术,所以垃圾回收变得很重要。 在说垃圾回收之前,先说说两个概念:托管代码,是由CLR管理的代码非托管代码,是由操作系统直接执行的代码在早期C++的时候...

dotNET跨平台 340

DotNet 资源大全

Awesome DotNet,这又是一个 Awesome XXX 系列的资源整理,由 quozd 发起和维护。内容包括:编译器、压缩、应用框架、应用模板、加密、数据库、反编译、IDE、日志、风格指南等。 伯乐在线已在 GitHub 上发起「DotNet 资源大全中文版」的整理。欢迎扩散、欢迎加入。 https://github.com/jobbole/aw

dotNET跨平台 2487

DotNet 垃圾回收

DotNet中垃圾回收 1>.只能回收内存资源,托管堆中资源(不可回收数据库连接,文件句柄,端口等). 2>.没有变量引用的对象,才会被垃圾回收(但是什么时候回收不能确定)4>.手动调用垃圾回收。一般不手动回收,由系统自动调用。(垃圾回收一系列算法,需要移动对象等等,这时为了达到目的,需要暂时应用程序的已处理,频繁的垃圾回收会影响系统性能):GC.Collect();...

weixin_30856965的博客 147

浅谈DotNet的垃圾回收机制

最近在做一个项目,用到了大量的非托管技术,所以垃圾回收变得很重要。 在说垃圾回收之前,先说说两个概念:托管代码,是由CLR管理的代码非托管代码,是由操作系统直接执行的代码在早期C++的时候...

farway000的博客 292

dotnet网上资源

相关网站列表http://blog.joycode.com/ 博客堂 主要是微软专家的帖子,内容较新http://www.cnblogs.com/ 博客园 http://www.microsoft.com/resources/practices/default.mspx 模式和实践首页http://msdn.microsoft.com/smartclient/ 智能客户端首页h...

161

dotNET资源回收的相关知识

protected override void Dispose( bool disposing )//重写Dispose() { if( disposing )//判断是否需要释放 { if (components != null) //如果co

482
上一篇: dotnet学习笔记一 - 装箱拆箱
下一篇: dotnet学习笔记六 - 无用资源回收之三
kenli
博客等级 码龄26年 1粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值