一,什么是GC

1,GC是垃圾回收器,一般来说系统会自动检测不会使用的对象或变量进行内存的释放,不需要手动调用,用Collect()就是强制进行垃圾回收,使内存得到及时的释放,让程序效率更高.

2,GC:只负责回收托管对象,不负责回收非托管对象。

那什么是垃圾? 垃圾是完全访问不到的东西了,就是当前程序执行后该对象或值没有被引用

如下图:

代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace TestDemo
  8. {
  9. public class TestDemo
  10. {
  11. private static Test t = new Test()//静态的不可能被回收 静态持有的引用也不会被回收
  12. {
  13. Id = ,
  14. Name = "Test"
  15. };
  16. public static void show()
  17. {
  18. ///{}这个括号是代码分块的意思,两个块之间是不影响的,第一块执行完后,一般来说就是会被主动GC释放
  19. ///而这里obj没有被释放的原因是因为静态遍历对obj这个引用类型变量的使用
  20. {
  21. object obj= new { Name = };
  22. t.obj = obj;
  23. int i = ;//都会被GC
  24. TestDemo testDemo = new TestDemo();//都会被GC
  25. }
  26. {
  27. GC.Collect();//主动GC
  28. }
  29. }
  30. }
  31.  
  32. public class Test
  33. {
  34. public int Id { get; set; }
  35. public string Name { get; set; }
  36. public object obj { get; set; }
  37. }
  38. }

总结:程序执行完会回收垃圾,这个obj还在静态的t使用,所以没有被释放

那GC怎么回收呢?
1,new的时候发现内存不够 就去遍历所有堆的对象,标记访问不到,然后启动一个线程来清理内存
2,清除标记了的对象,其他挪动,然后整齐摆放,所以这个时候全部线程停止,不允许操作内存
3,内存不够的是指一级对象的内存,有个临界值,也不是全部的堆的大小

GC回收执行的过程:
1, 首次GC前 全部对象都是0级
2, 第一次GC后,还保留的对象叫1级
3, 回收先找0级对象,如果空间还不够,再去找1级对象,这之后,还存在的对象就变成2级
4, 0级不够,1级也不够,2级还不够,那就内存溢出了
5,越是最近分配的,越是会被回收 比如for循环创建对象

大对象和正常的对象缓存的地址是不一样的。
大对象策略:如果大于某个值的对象85k,单独管理,用的是链表(碎片),避免频繁的内存移动

二,析构函数和IDisposable的区别?

~Class() 析构函数: 主要是用来释放非托管资源,等着GC的时候去把非托管资源释放掉 系统自动执行
GC回收的时候,CLR一定调用的,但是可能有延迟(释放对象不知道要多久呢)

Dispose() :也是释放非托管资源的,主动释放,方法本身是没有意义的,我们需要在方法里面实现对资源的释放
GC不会调用,而是用对象时,使用者主动调用这个方法,去释放非托管资源,
而不是说对象释放的时候,会去自动调用Dispose方法,然后在用完对象时,我们主动去执行dispose方法,当然可以是using的快捷方式

如下代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace TestDemo
  8. {
  9. public class TestDemoThree
  10. {
  11. public static void show()
  12. {
  13. {
  14. for (int i = ; i < ; i++)
  15. {
  16. TestThree @class = new TestThree()
  17. {
  18. Id = i,
  19. Name = "TestThree"
  20. };
  21. }
  22. }
  23. {
  24. GC.Collect(); //主动GC的时候,CLR一定调用的析构函数
  25. }
  26. {
  27. ///using 这个会去调用调用的dispose,相当于try后的finally
  28. using (TestThree TestThree = new TestThree()
  29. {
  30. Id = ,
  31. Name = ""
  32. })
  33.  
  34. try
  35. {
  36. //using相当于
  37. }
  38. finally
  39. {
  40. //调用的dispose()
  41. }
  42. }
  43. }
  44.  
  45. public class TestThree : IDisposable
  46. {
  47. public int Id { get; set; }
  48. public string Name { get; set; }
  49. ~TestThree()
  50. {
  51. Console.WriteLine($"执行{this.GetType().Name}~TestThreeDispose");
  52. }
  53. public void Dispose()
  54. {
  55. Console.WriteLine($"执行{this.GetType().Name}Dispose");
  56. }
  57. }
  58. }
  59. }

主动执行GC执行结果

using执行结果

C#GC垃圾回收和析构函数和IDisposable的使用的更多相关文章

  1. GC垃圾回收

    我们在开发需求的时候,可能很少关注到垃圾回收,因为我们绝大多数的时候都是使用的托管资源,托管资源的内存回收.net已经帮我们做了,但是.net的内存回收不是实时的,所以我们还是要关注下.net的垃圾回 ...

  2. 通俗易懂.NET GC垃圾回收机制(适用于小白面试,大牛勿喷)

    情景:你接到xx公司面试邀请,你怀着激动忐忑的心坐在对方公司会议室,想着等会的技术面试.技术总监此时走来,与你简单交谈后.... 技术:你对GC垃圾回收机制了解的怎么样? 你:还行,有简单了解过. 技 ...

  3. .Net平台的GC垃圾回收

    一.先了解下必备的知识前提 内存中的托管与非托管,可简单理解为: 托管:可借助GC从内存中释放的数据对象(以下要描述的内容点) 非托管:必须手工借助Dispose释放资源(实现自IDisposable ...

  4. 数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>

    C# 基础接口篇 一.多态复习 使用个new来实现,使用virtual与override    -->new隐藏父类方法 根据当前类型,电泳对应的方法(成员)    -->override ...

  5. GC垃圾回收算法

    什么是GC垃圾回收呢.日常生活中我们去餐厅吃饭吃完饭,吃完饭走了餐具不用管,服务员在把餐具拿走,这是一种方式,服务员怎么知道他要来把餐具拿走呢,因为你走了,这个位置空了.服务员什么时候拿走餐具很重要, ...

  6. JVM学习02:GC垃圾回收和内存分配

    JVM学习02:GC垃圾回收和内存分配 写在前面:本系列分享主要参考资料是  周志明老师的<深入理解Java虚拟机>第二版. GC垃圾回收和内存分配知识要点Xmind梳理 案例分析1-(G ...

  7. JVM和GC垃圾回收机制和内存分配

    JVM运行期间 线程共享 线程私有 线程共享: 方法区 堆方法区:存放可以共享数据,静态常量,类的共有方法属性字段等,可以共享的存在方法区. 堆:存放class对象 . 线程私有:本地方法栈 虚拟机栈 ...

  8. RPC调用与GC垃圾回收

    RPC调用 多个服务协同完成一次业务时,由于业务约束(如红包不符合使用条件.账户余额不足等).系统故障(如网络或系统超时或中断.数据库约束不满足等),都可能造成服务处理过程在任何一步无法继续,使数据处 ...

  9. Java虚拟机笔记(二):GC垃圾回收和对象的引用

    为什么要了解GC 我们都知道Java开发者在开发过程中是不需要关心对象的回收的,因为Java虚拟机的原因,它会自动回收那些失效的垃圾对象.那我们为什么还要去了解GC和内存分配呢? 答案很简单:当我们需 ...

随机推荐

  1. select * from (XXXXX)[字符]——写法解析

    步骤:1.先执行括号里的语句:查询 select id from three ,将查询出来的数据作为一个结果集 取名为 a2.然后 再 select * from a 查询a ,将 结果集a 全部查询 ...

  2. 装RAC跑脚本报错

    在执行第二个脚本的时候报错 原因是在改服务器找不到该包 解决方法: 挂载iso镜像,安装这个包

  3. http中post 和 get 请求方法区别

    前言 做Web开发就一定会涉及到浏览器和服务器的交互,所以了解浏览器和服务器交互的方式就尤为重要.从接触B/S开始就已经接触到了get和post,但是对它们的了解确实不深入.在后来不断的做项目过程中, ...

  4. 使用GitHub(一):添加SSHkey

    使用GitHub(一):添加SSHkey 本文简单介绍使用GitHub对代码进行版本控制,包括添加SSHkey.配置Git.使用Git创建版本库并在GitHub上进行管理,主要目的是对学习内容进行总结 ...

  5. awk命令1

    [root@a ~]# awk 'END{print NR}' c.txt       #没错,这就是文件的行数,当然,这种统计方法不是linux下最快的,但也是一种思路3[root@a ~]# wc ...

  6. Linux内核中的cmpxchg函数

    http://www.longene.org/forum/viewtopic.php?t=2216 前几天,为了这个函数花了好多时间,由于参考的资料有误,一直都没有看明白,直到google之后,总算搞 ...

  7. 由ES规范学JavaScript(二):深入理解“连等赋值”问题

    var foo={rzx:1} var bar =foo; foo.x=foo={rzx:100} console.log(foo.x) console.log(bar.x)   有这样一个热门问题: ...

  8. java数字加密算法

    数字加密在项目中时常会遇到,如手机号,身份证号信息等,下面小白将自己手写的数字加密算法分享给大家,可在项目中直接运用.加密规则,入参时传递一个字段时间戳 time:* 1.以字母代替数字,0-9分别为 ...

  9. Openstack 实现技术分解 (4) 通用技术 — TaskFlow

    目录 目录 前文列表 扩展阅读 简介 基本概念 实现样例 最后 前文列表 Openstack 实现技术分解 (1) 开发环境 - Devstack 部署案例详解 Openstack 实现技术分解 (2 ...

  10. 判断Ctrl Shift Alt 键当前是否被按下

    Control.ModifierKeys.HasFlag(Keys.Shift) 以此类推