当前位置:编程学习 > C#/ASP.NET >>

在while或for循环中,int n=1;,循环结束后,n是否消失了不再占资源了?

            while (true)
            {
                int n = 1;
                if(condition)
                    break;
            }

为什么这么问呢,因为我怕while循环的次数多了之后内存占用会越来越大。求解 --------------------编程问答-------------------- 不再占用资源了,因为它是只在循环内有效 --------------------编程问答--------------------
引用 1 楼 hdhai9451 的回复:
不再占用资源了,因为它是只在循环内有效

好的!那我就放心了 --------------------编程问答--------------------
引用 楼主 xjw163 的回复:
            while (true)
            {
                int n = 1;
                if(condition)
                    break;
            }

为什么这么问呢,因为我怕while循环的次数多了之后内存占用会越来越大。求解

是不是可以认为在下一个循环开始之前n就已经消失了? --------------------编程问答-------------------- 这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。 --------------------编程问答-------------------- 循环结束,系统就回收它的内存了,所以不存在占用 --------------------编程问答-------------------- 你的理解是错误的。
for (int j = 0; i < 10; j++)
{
    int i = 1;
    Console.WriteLine(i);
    i++;
}
只有第一次循环会设置为1。
这段代码输出1~10

引用 4 楼 youzelin 的回复:
这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。

不是这样的。

引用 5 楼 yu940822 的回复:
循环结束,系统就回收它的内存了,所以不存在占用

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

Quote: 引用 4 楼 youzelin 的回复:

这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。

不是这样的。

引用 5 楼 yu940822 的回复:
循环结束,系统就回收它的内存了,所以不存在占用

错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。

不好意思斑竹,按你的代码运行的话会提示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++;
  }
--------------------编程问答-------------------- --------------------编程问答--------------------
引用 6 楼 caozhy 的回复:
你的理解是错误的。
for (int j = 0; i < 10; j++)
{
    int i = 1;
    Console.WriteLine(i);
    i++;
}
只有第一次循环会设置为1。
这段代码输出1~10

Quote: 引用 4 楼 youzelin 的回复:

这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。

不是这样的。

引用 5 楼 yu940822 的回复:
循环结束,系统就回收它的内存了,所以不存在占用

错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。


不好意思,我不知道你的 1-10 是怎么出来的,我这边的答案是 十个 1 --------------------编程问答-------------------- 在程序调用结束后由回收机制自动回收,不必当心的。如果一直高速调用且参数比较大的话就需要一定的内存了,会报内存益出,他释放没那么快。像你这样定义一个很小的值类型是不用当心的。 --------------------编程问答--------------------
引用 10 楼 hzpdh 的回复:
在程序调用结束后由回收机制自动回收,不必当心的。如果一直高速调用且参数比较大的话就需要一定的内存了,会报内存益出,他释放没那么快。像你这样定义一个很小的值类型是不用当心的。


如果我加载的是一副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");
        }
--------------------编程问答--------------------
引用 楼主 xjw163 的回复:
            while (true)
            {
                int n = 1;
                if(condition)
                    break;
            }

为什么这么问呢,因为我怕while循环的次数多了之后内存占用会越来越大。求解


我们首先要问你,你是闲着没事写出来这个循环,还是有什么业务设计呢?

真正的业务操作会是一个定时、异步、事件驱动、主线程可刷新的动作,而不是胡乱写一个循环。 --------------------编程问答-------------------- 在一个程序没有运行结束前是不会释放的,即使你用来Dispose也没用的,如果真的业务需要,用线程试试? --------------------编程问答--------------------
引用 12 楼 sp1234 的回复:
Quote: 引用 楼主 xjw163 的回复:

            while (true)
            {
                int n = 1;
                if(condition)
                    break;
            }

为什么这么问呢,因为我怕while循环的次数多了之后内存占用会越来越大。求解


我们首先要问你,你是闲着没事写出来这个循环,还是有什么业务设计呢?

真正的业务操作会是一个定时、异步、事件驱动、主线程可刷新的动作,而不是胡乱写一个循环。

确实是程序需要才有此疑问,我已经在http://bbs.csdn.net/topics/390657118?page=1#post-396225086中回复了您。还望赐教 --------------------编程问答-------------------- 你用死循环干嘛\/? --------------------编程问答--------------------
引用 8 楼 wangweimutou 的回复:
 建议看看c#回收机制吧
http://www.cnblogs.com/guowenhui/archive/2011/10/26/2224661.html

终于又找到了这篇文章 --------------------编程问答--------------------
引用 15 楼 Windowsvipcuvs 的回复:
你用死循环干嘛\/?
只是为了说明问题,实际用的时候肯定是受控的,亲 --------------------编程问答-------------------- 其实是没有马上消失,这要归结net强大的析构器,不过楼主放心使用。不会占你很多内存,析构器会在必要时清理你的无效内存。之以说必要时,是因为析构器本身就不是定时在清理,应该是你内存无效内存到一定量时。 --------------------编程问答--------------------
引用 9 楼 youzelin 的回复:
Quote: 引用 6 楼 caozhy 的回复:

你的理解是错误的。
for (int j = 0; i < 10; j++)
{
    int i = 1;
    Console.WriteLine(i);
    i++;
}
只有第一次循环会设置为1。
这段代码输出1~10

Quote: 引用 4 楼 youzelin 的回复:

这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。

不是这样的。

引用 5 楼 yu940822 的回复:
循环结束,系统就回收它的内存了,所以不存在占用

错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。


不好意思,我不知道你的 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 楼 maomiaomi 的回复:
Quote: 引用 6 楼 caozhy 的回复:

你的理解是错误的。
for (int j = 0; i < 10; j++)
{
    int i = 1;
    Console.WriteLine(i);
    i++;
}
只有第一次循环会设置为1。
这段代码输出1~10

Quote: 引用 4 楼 youzelin 的回复:

这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。

不是这样的。

引用 5 楼 yu940822 的回复:
循环结束,系统就回收它的内存了,所以不存在占用

错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。

不好意思斑竹,按你的代码运行的话会提示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++;
  }

是我说错了,十分抱歉。 --------------------编程问答--------------------
引用 19 楼 caozhy 的回复:
Quote: 引用 9 楼 youzelin 的回复:

Quote: 引用 6 楼 caozhy 的回复:

你的理解是错误的。
for (int j = 0; i < 10; j++)
{
    int i = 1;
    Console.WriteLine(i);
    i++;
}
只有第一次循环会设置为1。
这段代码输出1~10

Quote: 引用 4 楼 youzelin 的回复:

这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。

不是这样的。

引用 5 楼 yu940822 的回复:
循环结束,系统就回收它的内存了,所以不存在占用

错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。


不好意思,我不知道你的 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


长姿势了!想问下汇编码这个东西在哪里可以查到? --------------------编程问答--------------------
引用 21 楼 xjw163 的回复:
Quote: 引用 19 楼 caozhy 的回复:

Quote: 引用 9 楼 youzelin 的回复:

Quote: 引用 6 楼 caozhy 的回复:

你的理解是错误的。
for (int j = 0; i < 10; j++)
{
    int i = 1;
    Console.WriteLine(i);
    i++;
}
只有第一次循环会设置为1。
这段代码输出1~10

Quote: 引用 4 楼 youzelin 的回复:

这段代码发生的一件事情是:不断的在循环内创建 整型变量 i。

不是这样的。

引用 5 楼 yu940822 的回复:
循环结束,系统就回收它的内存了,所以不存在占用

错,循环结束不会“回收”,而是在函数退出的时候,清堆栈的时候才销毁。


不好意思,我不知道你的 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调试的状态下在菜单调试-窗口下有 --------------------编程问答-------------------- 我服了,明明栈上的事情有人竟然连GC都扯出来了
int n=1就是

 mov dword ptr [rsp+20h],1 

每次都是rsp+20h,不会占用新的空间的 --------------------编程问答-------------------- 不会滴,int i 离开 while之后 被 pop 了
但如果是递归函数调用,就会占用内存,直到stack耗尽 --------------------编程问答--------------------
引用 11 楼 xjw163 的回复:
Quote: 引用 10 楼 hzpdh 的回复:

在程序调用结束后由回收机制自动回收,不必当心的。如果一直高速调用且参数比较大的话就需要一定的内存了,会报内存益出,他释放没那么快。像你这样定义一个很小的值类型是不用当心的。


如果我加载的是一副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)
                {

                }

            }

--------------------编程问答--------------------
引用 25 楼 maomiaomi 的回复:
Quote: 引用 11 楼 xjw163 的回复:

Quote: 引用 10 楼 hzpdh 的回复:

在程序调用结束后由回收机制自动回收,不必当心的。如果一直高速调用且参数比较大的话就需要一定的内存了,会报内存益出,他释放没那么快。像你这样定义一个很小的值类型是不用当心的。


如果我加载的是一副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就是为了测试用的 --------------------编程问答-------------------- 参照一下变量的作用域
循环内部变量退出循环便会销毁 
楼主的循环每次执行到
int n = 1;都会重新声明
--------------------编程问答--------------------
引用 27 楼 shengguang1587 的回复:
参照一下变量的作用域
循环内部变量退出循环便会销毁 
楼主的循环每次执行到
int n = 1;都会重新声明

不会滴,只会第一次分配内存,以后每次都是赋值。.net对while之类的语法有优化的。
就好像你的for判断里有函数也不会每次都执行一样。 --------------------编程问答--------------------
引用 28 楼 yuwenge 的回复:
Quote: 引用 27 楼 shengguang1587 的回复:

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

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

内存相同 但是会重新赋值了~ 
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,