1.C#有自动垃圾回收的机制,但是它一般在什么时候回收呢.在当程序内存使用上升到某个值时会回收,还是程序运行过了一定时间后回收呢?
我这里有一个C#写的程序,是以系统服务运行的,一般不会重启,里面的函数在写的时候都没有专门的释放创建的对象。我想问一下长时间运行下去,会导致进程的内存使用率慢慢增加吗?2.我之前测试了一下,不断创建对象看什么时候会进行垃圾回收,发现在8G内存的服务器上运行我的测试程序,好像是每到150M内存左右的时候就会回收一下,回到70M左右继续增加到150M左右又进行一次...这个是依据什么来进行回收的呢?3.当调用完一个函数之后,这个函数里创建的对象是不是就变成可回收状态了呢?如果是静态方法的话是不是也这样呢?4.如果在函数return这一句之前加上GC.collect()来强制垃圾回收,那么它会回收这个函数前面创建的对象吗,我测试的感觉好像是不会,在函数最后一句加GC.collect()好像没有用,在调用这个函数之后加GC.collect()才可以。
但这样每次就要在调用函数之后再加上GC.collect()才行,会比较麻烦,有没有办法直接在函数中就做到呢。
我这里有一个C#写的程序,是以系统服务运行的,一般不会重启,里面的函数在写的时候都没有专门的释放创建的对象。我想问一下长时间运行下去,会导致进程的内存使用率慢慢增加吗?2.我之前测试了一下,不断创建对象看什么时候会进行垃圾回收,发现在8G内存的服务器上运行我的测试程序,好像是每到150M内存左右的时候就会回收一下,回到70M左右继续增加到150M左右又进行一次...这个是依据什么来进行回收的呢?3.当调用完一个函数之后,这个函数里创建的对象是不是就变成可回收状态了呢?如果是静态方法的话是不是也这样呢?4.如果在函数return这一句之前加上GC.collect()来强制垃圾回收,那么它会回收这个函数前面创建的对象吗,我测试的感觉好像是不会,在函数最后一句加GC.collect()好像没有用,在调用这个函数之后加GC.collect()才可以。
但这样每次就要在调用函数之后再加上GC.collect()才行,会比较麻烦,有没有办法直接在函数中就做到呢。
如果对象也都没有置null处理,但我是在函数内部最后的return之前调用,这时对象可以被回收吗?
也就是下面两种情况,创建的MyObj对象会被GC.collect回收吗情况一:public void fun()
{
MyObj test = new MyObj();
//.......
return;
}public void fun2()
{
fun();
GC.collect();
}
情况二:public void fun()
{
MyObj test = new MyObj();
//.......
GC.collect();
return;
}
public void fun2()
{
fun();
}
{
MyObj test = new MyObj();
//.......
GC.collect();
return;
}
调用GC.collect()时,test仍然有效,无法回收。
情况一中因为超过作用域,可以被回收。
比如MyObj test = new MyObj();
test.MyFunction();
test = null
GC.collect();即使是这样,我把方法放在类里,创建完对象后把对象设置为null,调用GC.collect()仍然不会回收.
我创建循环调用它的话,就会看到内存一直在涨.
但我是指的test.MyFunction方法中创建的对象也不能被回收,这些对象既不是静态的,也不是MyObj的成员变量,就是MyFunction里面定义的。
强制执行GC.Collect方法,
windows报告内存不足,CLR将强制执行垃圾回收。
CLR卸载AppDomain时,GC将对所有代龄的对象执行垃圾回收。 简单介绍一下代龄:垃圾收集器将托管堆中的对象分为三代:0(容量256KB),1(容量2MB),2(容量10MB),其中第0代对象的回收的效率最高,CLR初始化后,被添加到托管堆中的对象都被定为第0代,当有垃圾回收执行时,未被回收的对象代龄将提升一级,变成第1代对象,而后新建的对象仍为第0代对象。也就是说代龄越小,表示对象越新,通常情况下生命周期越短。因此垃圾收集器总是首先回收第0代的不可到达对象的内存。那对1代对象的收集是什么时候呢?第0代对象内存不足以创建新的对象,同时第1代对象的体积也超出了容量值时,垃圾回收器将同时对0代和1代对象进行垃圾回收。回收后未被收回的1代对象升级为2代对象,未被回收的0代对象升级为1代对象,而后新建的对象仍为第0代。垃圾收集正式上述过程的不断重复。 以上都是涉及是关于.net对于托管资源的回收,至于对于非托管的资源(包括数据库连接,文件句柄,网络连接,COM对象等)是利用2种方式(Finalize和Dispose)来实现的,具体就不说了。