ASP.NET 崩溃SiteMap中疯狂的循环

分类: asp.net技巧   出处:iocblog整理  更新时间:2009-02-24   添加到收藏  

原文地址:http://blogs.msdn.com/tess/archive/2006/10/10/asp.net-crash-_2d00_-crazy-looping-in-a-sitemap.aspx
发布时间:tuesday, october 10, 2006 4:10 pm
作  者:tess      

一天,我收到了一封有关我的博客的邮件,提出如下问题,简述如下:
 
我想快速地创建一个站点地图,因此我重写了buildsitemap()方法,在里面我写了一个循环,用以添加一些仿造的sitemap节点。


public override sitemapnode buildsitemap(){
   for (int i = 0; i < 5; i++)
      myroot.childnodes.add(new sitemapnode(this, i.tostring(), i.tostring(), i.tostring()));
   return myroot;
}

运行程序,就发生堆栈溢出,服务器也崩溃了。我用调试器单步调试,发现真的很奇怪: 

1) int i = 0
2) i < 5
3) myroot...
4) int i = 0
5) i < 5
etc.

i的值看起来从来没有增加,除非我调用到sitemapnode(access a property, call a method),看起来这个循环是正确的。
是什么使得这个循环不确定呢?咋看可能是编译器或者是clr的一个bug.

(当我获此问题时,我真不知道asp.net2.0中的站点导航,但我找到了这些文章... http://weblogs.asp.net/scottgu/archive/2005/11/20/431019.aspx 和http://aspnet.4guysfromrolla.com/articles/111605-1.aspx ,叙述得真是很不错.)

 

最初的想法


这个问题最重要的就是它始终重新开始, 这就意味着可以对此做现场调试。但我们暂不走那么远,先回头看看现在有什么...


1. 堆栈溢出


2. 一次又一次重新开始的循环


 我已经在先前的博客帖子里讨论过堆栈溢出,现在重复一下...    引起堆栈溢出的原因是, 分配了太多的函数指针,变量指针和参数,以致在堆栈里申请的内存数量不够用。到目前为止,堆栈溢出最平常的原因是无终止的递归。换句话说,function a调用了function b, function b又调用了function a...


因此,callstack看上去有点像这样....


...
functionb()
functiona()
functionb()
functiona() 


好了,一切都好极了,但那仅仅解释了堆栈溢出。那么疯狂的循环是怎么回事呢?
 
好...想象一下有这样一个函数(在-->处有有一个断点)


void myrecursivefunction(){
     for(int i=0; i<5; i++){
-->      myrecursivefunction();
     }
}


当你第一次停在断点处,i的值应该是0,callstack看起来是这样的...


myrecursivefunction()
...

 

现在调用myrecrusive函数,每一次调用这个函数自己,会再一次出现 i=0(虽然我们并不真的在同一个loop里)。若调用myrecrusive这个函数几个来回,并用实际执行的代码代替之,它将执行类似如下的代码:


for(int i=0; i<5; i++){
   for(int i2=0; i2<5; i2++){
      for(int i3=0; i3<5; i3++){
         for(int i4=0; i4<5; i4++){
            for(int i5=0; i5<5; i5++){
               for(int i6=0; i6<5; i6++){
                  for(int i7=0; i7<5; i7++){
                     ...
                  }
               }
            }
         }
      }
   }
}


... 在visual studio中查看它,看起来总是运行同样的循环,且并不改变变量i的值。暂时,你对此不会有深层次的理解,直到你真正看到堆栈调用。
假如我们看一下callstack, callstack现在看起来是这样的...

myrecursivefunction()
myrecursivefunction()
myrecursivefunction()
myrecursivefunction()
myrecursivefunction()
myrecursivefunction()
myrecursivefunction()
...

[1] [2] 下一页


Tag: SiteMap



文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。