关于GC进行垃圾回收的时机

时间:2021-05-13 00:40:17

前言


今天查看一个同事的代码,发现代码中多处地方使用了GC.Collect()方法,我问他为什么这么做,他说感觉程序中定义了好多变量,怕GC回收不及时,用GC.Collect()可以手动掌控GC进行垃圾回收。

先不说他对GC的垃圾回收机制还不了解,就是调用GC.Collect()后GC真的会不会回收这个问题都需要再深入了解一下。

GC.Collect


下面我们通过一个小例子,来看一下使用GC.Collect后的内存情况。

我们知道可以通过GCHandle设置引用类型(可直接复制到本机结构中的类型)在GC垃圾回收时不移动地址,并且获取地址值,那么就可以通过在两次地址获取中间加入Collect方法,来判断GC是否真的进行了垃圾回收。

using System;
using System.Runtime.InteropServices; namespace TestGCCollect
{
class Program
{
static void Main(string[] args)
{
//创建一个没有引用的垃圾对象
new object();
//这是我们要判定地址的对象
int[] gcTest = new int[]; //设定Pinned通知GC在进行回收的时候不移动地址
GCHandle gcHandle1 = GCHandle.Alloc(gcTest, GCHandleType.Pinned);
//获取gcTest在堆中的地址并输出
IntPtr add1 = gcHandle1.AddrOfPinnedObject();
Console.WriteLine(add1.ToString());
//通知GC当程序返回的时候可以回收
gcHandle1.Free(); //调用GC回收object垃圾
GC.Collect(); //再次获取地址
GCHandle gcHandle2 = GCHandle.Alloc(gcTest, GCHandleType.Pinned);
IntPtr add2 = gcHandle2.AddrOfPinnedObject();
Console.WriteLine(add2.ToString());
gcHandle2.Free(); Console.ReadKey();
}
}
}

关于GC进行垃圾回收的时机

我们发现地址并没有变化!

修改一下代码使用for循环生成多个object:

            //创建没有引用的垃圾对象
for (int i = ; i < ; i++)
new object();
//这是我们要判定地址的对象
int[] gcTest = new int[];

重新编译后,执行结果如下:

关于GC进行垃圾回收的时机

地址变了!

通过上面的代码,我们知道GC.Collect并不是只要执行就会进行垃圾回收,实际上GC会首先判断当前是不是真的需要进行回收,如果内存中只有很小的垃圾(碎片化不严重)时,这时候启动回收显然得不偿失,影响性能。

总结


1. 永远都不要手动进行GC.Collect操作。如果你认为有,需要检查你地代码

2. 即使当你手动进行垃圾回收时,GC还不会立即执行,它要先判断是否真正需要回收

关于GC进行垃圾回收的时机的更多相关文章

  1. java&colon; system&period;gc&lpar;&rpar;和垃圾回收机制finalize

    System.gc()和垃圾回收机制前的收尾方法:finalize(收尾机制) 程序退出时,为每个对象调用一次finalize方法,垃圾回收前的收尾方法 System.gc() 垃圾回收方法 clas ...

  2. 【转载】Java性能优化之JVM GC(垃圾回收机制)

    文章来源:https://zhuanlan.zhihu.com/p/25539690 Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我 ...

  3. Java性能优化之JVM GC(垃圾回收机制)

    Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.st ...

  4. System&period;GC&period;Collect&lpar;&rpar;&semi;&sol;&sol;垃圾回收,回收没有正常关闭的http连接

    System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接

  5. Java GC(垃圾回收)机制知识总结

    目录 Java GC系列 Java关键术语 Java HotSpot 虚拟机 JVM体系结构 Java堆内存 启动Java垃圾回收 Java垃圾回收过程 垃圾回收中实例的终结 对象什么时候符合垃圾回收 ...

  6. gc roots 垃圾回收

    gc roots包括以下几个: 虚拟机栈(栈桢中的本地变量表)中的引用对象 方法区中的类静态属性引用的对象 方法区中的常量引用的对象 本地方法栈中JNI(即native方法)的引用的对象 java,c ...

  7. GC(垃圾回收)

    Java程序的内存分配和回收都是由JRE在后台自动进行的.JRE会负责回收那些不再使用的内存,这种机制被称为垃圾回收GC.通常JRE会提供一条超级线程来进行检测和控制,一般都是在CPU空闲或内存不足时 ...

  8. jvm GC:垃圾回收的测试与分析

    实验环境: (1)Java版本以及模式: java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0 ...

  9. 关于GC(垃圾回收)

    当我用new创建一个对象时,当可分配的内存不足GC就会去回收未使用的对象,但是GC的操作是非常复杂的,会占用很多CPU时间,对于移动设备来说频繁的垃圾回收会严重影响性能.下面的建议可以避免GC频繁操作 ...

随机推荐

  1. C&num; winfrom HttpWebRequest 请求获取html网页信息和提交信息

    string result =GetRequest("http://localhost:32163/DuoBao/ajax.aspx", "time=5"); ...

  2. BeanUtils&period;copyProperties和PropertyUtils&period;copyProperties的使用区别

    http://caoyaojun1988-163-com.iteye.com/blog/1871316

  3. 求第K大数

    1.排序找第K个数 2.快速排序分块  时间复杂度  2呢

  4. 让ASP&period;NET Web API支持POST纯文本格式&lpar;text&sol;plain&rpar;的数据

    今天在web api中遇到了这样一个问题,虽然api的参数类型是string,但只能接收post body中json格式的string,不能接收原始string. web api是这样定义的: pub ...

  5. Metasploit启动

    一.启动Kali的PostgreSQL服务 由于使用PostgreSQL作为数据库,因此,必须先运行它. root@kali:~# service postgresql start 使用ss -ant ...

  6. 转:基于Webrtc的跨平台实时语音通信解决方案(讲座)

    转:http://edu.csdn.net/course/detail/320/

  7. DIP开放计算平台介绍

    随着平台业务的发展,依赖于Portal(Web)构建的服务架构已逐渐不能满足现有的一些复杂需求(如:使用Hive SQL无法完成计算逻辑),而且对于一些具备编程能力的程序员或数据分析师而言,能够自主控 ...

  8. &lbrack;转载&rsqb; Redis-benchmark使用总结

    转载自http://blog.csdn.net/jiangguilong2000/article/details/24143721 Redis-benchmark为Redis性能测试工具. 指令说明: ...

  9. 【nodejs】初识 NodeJS(三)

    上节我们将 http 服务器(server.js)和请求路由模块(route.js)整合在一起了,当然这还不够,路由,顾名思义,是指我们要针对不同的 url 有不同的处理方式. 请求处理程序模块(re ...

  10. Ubuntu下忘记MySQL root密码解决方法

    1.忘了mysql密码,从网上找到的解决方案记录在这里. 编辑mysql的配置文件/etc/mysql/my.cnf,在[mysqld]段下加入一行“skip-grant-tables”. 2.重启服 ...