你的理解是错误的。
for (int j = 0; i < 10; j++)
{
    int i = 1;
    Console.WriteLine(i);
    i++;
}
只有第一次循环会设置为1。
这段代码输出1~10不是这样的。错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。

解决方案 »

  1.   

    不是这样的。错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。
    不好意思斑竹,按你的代码运行的话会提示for (int j = 0; i < 10; j++)中的i没有定义
    而如果改成for (int j = 0; j < 10; j++),则输出是10个1
    因为虽然再开始一次循环后i没有被清理,但是做了一个i=1的赋值动作,呵呵
    以下代码是可以打印出1-10的,如果VS不做编译时检测而提示CS0165的话
    for (int j = 0; j < 10; j++)
    {
    int i;
         Console.WriteLine(i);
          i++;
      }
      

  2.   


    如果我加载的是一副BMP图像的话,我发现即使方法调用结束也不回收,有解决的办法吗?
    public void tescRAM()
            {
                int count = 0;
                while (count<20000)
                {
                    try
                    {
                        Bitmap a = new Bitmap("d:/a.bmp");
                        count++;
                    }
                    catch
                    {
                        MessageBox.Show(count.ToString());
                        break;
                    }
                    //a.Dispose();
                }
                MessageBox.Show("over");
            }
      

  3.   

    在一个程序没有运行结束前是不会释放的,即使你用来Dispose也没用的,如果真的业务需要,用线程试试?
      

  4.   


    我们首先要问你,你是闲着没事写出来这个循环,还是有什么业务设计呢?真正的业务操作会是一个定时、异步、事件驱动、主线程可刷新的动作,而不是胡乱写一个循环。
    确实是程序需要才有此疑问,我已经在http://bbs.csdn.net/topics/390657118?page=1#post-396225086中回复了您。还望赐教
      

  5.   

    其实是没有马上消失,这要归结net强大的析构器,不过楼主放心使用。不会占你很多内存,析构器会在必要时清理你的无效内存。之以说必要时,是因为析构器本身就不是定时在清理,应该是你内存无效内存到一定量时。
      

  6.   

    不是这样的。错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。不好意思,我不知道你的 1-10 是怎么出来的,我这边的答案是 十个 1嗯,我错了。是这样的看如下汇编代码:            for (int j = 0; j < 10; j++)
    009A2661  xor         edx,edx  
    009A2663  mov         dword ptr [ebp-40h],edx  
    009A2666  nop  
    009A2667  jmp         009A2695  
                {
    009A2669  nop  
                    int i = 1;
    009A266A  mov         dword ptr [ebp-44h],1  
                    i++;
    009A2671  mov         eax,dword ptr [ebp-44h]  
    009A2674  mov         dword ptr [ebp-48h],eax  
    009A2677  mov         eax,dword ptr [ebp-48h]  
    009A267A  inc         eax  
    009A267B  mov         dword ptr [ebp-44h],eax  
                    Console.WriteLine(i);
    009A267E  mov         ecx,dword ptr [ebp-44h]  
    009A2681  call        71D29090  
    009A2686  nop  
                }可以看到,i在堆栈上只有1个(堆栈基地址-0x44)。而不是每次都会产生一个。
    但是的确每次遇到int i = 1;都会执行一次i = 1
      

  7.   

    不是这样的。错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。
    不好意思斑竹,按你的代码运行的话会提示for (int j = 0; i < 10; j++)中的i没有定义
    而如果改成for (int j = 0; j < 10; j++),则输出是10个1
    因为虽然再开始一次循环后i没有被清理,但是做了一个i=1的赋值动作,呵呵
    以下代码是可以打印出1-10的,如果VS不做编译时检测而提示CS0165的话
    for (int j = 0; j < 10; j++)
    {
    int i;
         Console.WriteLine(i);
          i++;
      }
    是我说错了,十分抱歉。
      

  8.   

    不是这样的。错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。不好意思,我不知道你的 1-10 是怎么出来的,我这边的答案是 十个 1嗯,我错了。是这样的看如下汇编代码:            for (int j = 0; j < 10; j++)
    009A2661  xor         edx,edx  
    009A2663  mov         dword ptr [ebp-40h],edx  
    009A2666  nop  
    009A2667  jmp         009A2695  
                {
    009A2669  nop  
                    int i = 1;
    009A266A  mov         dword ptr [ebp-44h],1  
                    i++;
    009A2671  mov         eax,dword ptr [ebp-44h]  
    009A2674  mov         dword ptr [ebp-48h],eax  
    009A2677  mov         eax,dword ptr [ebp-48h]  
    009A267A  inc         eax  
    009A267B  mov         dword ptr [ebp-44h],eax  
                    Console.WriteLine(i);
    009A267E  mov         ecx,dword ptr [ebp-44h]  
    009A2681  call        71D29090  
    009A2686  nop  
                }可以看到,i在堆栈上只有1个(堆栈基地址-0x44)。而不是每次都会产生一个。
    但是的确每次遇到int i = 1;都会执行一次i = 1长姿势了!想问下汇编码这个东西在哪里可以查到?
      

  9.   

    不是这样的。错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。不好意思,我不知道你的 1-10 是怎么出来的,我这边的答案是 十个 1嗯,我错了。是这样的看如下汇编代码:            for (int j = 0; j < 10; j++)
    009A2661  xor         edx,edx  
    009A2663  mov         dword ptr [ebp-40h],edx  
    009A2666  nop  
    009A2667  jmp         009A2695  
                {
    009A2669  nop  
                    int i = 1;
    009A266A  mov         dword ptr [ebp-44h],1  
                    i++;
    009A2671  mov         eax,dword ptr [ebp-44h]  
    009A2674  mov         dword ptr [ebp-48h],eax  
    009A2677  mov         eax,dword ptr [ebp-48h]  
    009A267A  inc         eax  
    009A267B  mov         dword ptr [ebp-44h],eax  
                    Console.WriteLine(i);
    009A267E  mov         ecx,dword ptr [ebp-44h]  
    009A2681  call        71D29090  
    009A2686  nop  
                }可以看到,i在堆栈上只有1个(堆栈基地址-0x44)。而不是每次都会产生一个。
    但是的确每次遇到int i = 1;都会执行一次i = 1长姿势了!想问下汇编码这个东西在哪里可以查到?
    VS调试的状态下在菜单调试-窗口下有
      

  10.   

    我服了,明明栈上的事情有人竟然连GC都扯出来了
    int n=1就是 mov dword ptr [rsp+20h],1 每次都是rsp+20h,不会占用新的空间的
      

  11.   

    不会滴,int i 离开 while之后 被 pop 了
    但如果是递归函数调用,就会占用内存,直到stack耗尽
      

  12.   


    如果我加载的是一副BMP图像的话,我发现即使方法调用结束也不回收,有解决的办法吗?
    public void tescRAM()
            {
                int count = 0;
                while (count<20000)
                {
                    try
                    {
                        Bitmap a = new Bitmap("d:/a.bmp");
                        count++;
                    }
                    catch
                    {
                        MessageBox.Show(count.ToString());
                        break;
                    }
                    //a.Dispose();
                }
                MessageBox.Show("over");
            }
    对于这种占资源的临时变量,从来都是建议用完就直接dispose,另外你这里写了个dispose是不是不知道如何调用呢?这里建议使用using,超出范围自动回收,如下所示
                int count = 0;
                while (count<2000)
                {
                    try
                    {
                        using (Bitmap bitmap=new Bitmap("d:\\unn.bmp"))
                        {
                           count++; 
                        }
                    }
                    catch (Exception)
                    {                }            }
      

  13.   


    如果我加载的是一副BMP图像的话,我发现即使方法调用结束也不回收,有解决的办法吗?
    public void tescRAM()
            {
                int count = 0;
                while (count<20000)
                {
                    try
                    {
                        Bitmap a = new Bitmap("d:/a.bmp");
                        count++;
                    }
                    catch
                    {
                        MessageBox.Show(count.ToString());
                        break;
                    }
                    //a.Dispose();
                }
                MessageBox.Show("over");
            }
    对于这种占资源的临时变量,从来都是建议用完就直接dispose,另外你这里写了个dispose是不是不知道如何调用呢?这里建议使用using,超出范围自动回收,如下所示
                int count = 0;
                while (count<2000)
                {
                    try
                    {
                        using (Bitmap bitmap=new Bitmap("d:\\unn.bmp"))
                        {
                           count++; 
                        }
                    }
                    catch (Exception)
                    {                }            }

    谢谢你,那个dispose就是为了测试用的
      

  14.   

    参照一下变量的作用域
    循环内部变量退出循环便会销毁 
    楼主的循环每次执行到
    int n = 1;都会重新声明
      

  15.   

    不会滴,只会第一次分配内存,以后每次都是赋值。.net对while之类的语法有优化的。
    就好像你的for判断里有函数也不会每次都执行一样。
      

  16.   

    不会滴,只会第一次分配内存,以后每次都是赋值。.net对while之类的语法有优化的。
    就好像你的for判断里有函数也不会每次都执行一样。
    内存相同 但是会重新赋值了~