vsdebug release 区别和debug的区别

程序Release 和Debug的区别_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
程序Release 和Debug的区别
上传于|0|0|文档简介
&&在程序的编译设置中,debug和release的设置对程序到底有什么影响!本文简要介绍了一下。
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢博客访问: 435949
博文数量: 155
博客积分: 4015
博客等级: 上校
技术积分: 1623
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
& 有时我们在运行程序时,会出现Debug版本和Release版本运行结果不一致的情况。现给出C#中的一个例子,这个例子是Jeffrey在他的《CLR via C#》中"垃圾回收"这一章给出的,很有意思。
& 其实大家也会猜测,Debug版和Release版编译后的代码肯定会有不一样的地方,是的!是会这样的。要不然也不会出现运行结果不一致,呵呵!闲话不说我们来看看代码,代码很简单。(调试环境WinXP + VS2003 + C#)
&&&&class Program&&&&{&&&&&&&&[STAThread]&&&&&&&&static void Main(string[] args)&&&&&&&&{&&&&&&&&&&&&TimerCallback tm = new TimerCallback(ShowTime);&&&&&&&&&&&&Timer t = new Timer(tm,null,0,2000);&&&&&&&&&&&&Console.ReadLine();&&&&&&&&&&&&//t.Dispose(); (1)&&&&&&&&}&&&&&&&&private static void ShowTime(Object o)&&&&&&&&{&&&&&&&&&&&&Console.WriteLine(DateTime.Now.ToString());&&&&&&&&&&&&GC.Collect();& //强制GC (2)&&&&&&&&}&&&&}
& 你可以在Debug版本中运行一下,会发现该报时程序工作正常(一直会报时)。而在Release版本中时间报只显示一下。
& 为什么呢?这是因为我们在(2)处强制了一次GC(Garbage Collect)即垃圾回收。在Release版中当我们程序运行到GC.Collect()时,Timer类型对象t是可以被GC的。但Debug版本中t是作为一个本地参数而不能被GC的。
& 我们再分解一下整个过程(仅列出关键过程):
1,创建Timer类型对象t;
2,t定时调用委托
3,tm方法执行;
4,tm方法进行Garbage C
5,待读取一行字符;(其间t定时器重复执行步骤2)
& 可以看出第4,5步是个关键,如果我们一直等待输入就能不停打印。但问题是:
在Debug版中确实是这样的,在Release版中却只打印了一次....How mysterious!
&&TOM:&&&&这时t是不是不工作了?
& JERRY:& 对的,如果是Release版本中,至第5步时t确实不工作了,因为:它已经不存在了,被GC了.
& TOM:&&&&不....不....不,你慢一点,别忽悠我^_^!!!,那Debug版为什么它就不被GC呢?
& JERRY:& 这是因它,它在Debug版中不符合GC的条件.
& TOM:&&&&你鼻子变长了....
& JERRY:&&不信? 你看...这,这,这,诺..还有这.
&& 为了让TOM相信这是真的,JERRY用ILDasm分别打开了Debug版本和Release版本的程序并双击打开Main方法.
------------
-------------------------------------------------
& .........省略了一些行........& // 代码大小&&&&&& 32 (0x20)& .maxstack& 5& .locals ([0] class [mscorlib]System.Threading.Timer t)& IL_0000:& ldnull& IL_0001:& ldftn&&&&& void Class1.Program::ShowTime(object)& IL_0007:& newobj&&&& instance void [mscorlib]
&&&&&&&&&&&&&&&&&&&&&& System.Threading.TimerCallback::.ctor(object,native int)& IL_000c:& ldnull& IL_000d:& ldc.i4.0& IL_000e:& ldc.i4&&&& 0x7d0& IL_0013:& newobj&&&& instance void [mscorlib]System.Threading.Timer::.ctor
&&&&&&&&&&&&&&&&&&&&&& (class[mscorlibSystem.Threading.TimerCallback,
&&&&&&&&&&&&&&&&&&&&&& object,int32,int32)& IL_0018:& stloc.0& IL_0019:& call&&&&&& string [mscorlib]System.Console::ReadLine()&&& IL_001e:& pop&& & IL_001f:& ret&& //仍可使用t对象} // end of method Program::Main
-------------------------------------------------
& 在Debug版中我们定义的t是作为一个本地参数(locals[0]),在IL_0018位置,它参考到新new的Timer对象.这时需要注意一点是的,即使在IL_001f处,仍通过locals[0]引用到t对象.
& 所以在托管堆(Managed Heap)中,该对象仍象是可达对象(Reachable object).也就不符合被回收的条件。所以只要Main函数不结束,t就不能被回收。
---------------
Release版:
-------------------------------------------------& .........省略了一些行........& // 代码大小&&&&&& 32 (0x20)& .maxstack& 5& IL_0000:& ldnull& IL_0001:& ldftn&&&&& void Class1.Program::ShowTime(object)& IL_0007:& newobj&&&& instance void [mscorlib]
&&&&&&&&&&&&&&&&&&&&&& System.Threading.TimerCallback::.ctor(object,native int)& IL_000c:& ldnull& IL_000d:& ldc.i4.0& IL_000e:& ldc.i4&&&& 0x7d0& IL_0013:& newobj&&&& instance void [mscorlib]System.Threading.Timer::.ctor
&&&&&&&&&&&&&&&&&&&&&& (class[mscorlibSystem.Threading.TimerCallback,
&&&&&&&&&&&&&&&&&&&&&& object,int32,int32)& IL_0018:& pop& IL_0019:& call&&&&&& string [mscorlib]System.Console::ReadLine()& IL_001e:& pop& IL_001f:& ret&&& //至此,也没有办法可以refer to至t对象,t可以被Garbage Collect} // end of method Program::Main
-------------------------------------------------
& 而在Rlease版中位置:IL_0018只用了pop方法弹出该对象(也就是t对象).这相当于丢弃了t对象,这时t被标记为可回收。
& 但有一点需要了解的是:t虽被丢弃,还仍存活在托管堆(Managed Heap)中,直到t调用ShowTime,而在ShowTime函数中调用GC为止。当ShowTime中调用GC时,由于t被标记为可回收,所以t对象被回收。整个过程看起来是这个样子的:
& 正是由于在Release版本中t是作为临时变量,用完后被GC强制回收,所以t只能工作一次,便通过调用GC结束了自己的生命,可怜的娃!
& 为了使Debug版和Release运行结果保持一致,你可以有两个选择:
& 1,在Console.ReadLine只后调用t.Dispose(),即取消我最先给出的代码的(1)处的注释。因为t对象在创建之后还要被引用,所以创建的t对象也被作为一个本地参数来保存,生成的IL如下:
&& .locals init (class [mscorlib]System.Threading.Timer V_0)
& 2,注释掉我最先给出的代码的(2)处的GC.Collect函数的调用.这样虽然在Release版中t对象已被标识为可回收,但些时没有内存需求(这只是一个假设),CLR并不会回收t对象.
&&&& 显然方法2是不可取的,我们只把希望寄托在CLR不进行Garbage Collect,但在现实编程中这是不现实的。在t被触发的间隔间谁也不能保证CLR不进行Garbage Collect.若使用方法2我稍改了一下代码,Release版本的程序又不能工作了。
&&&&class Program&&&&{&&&&&&&&[STAThread]&&&&&&&&static void Main(string[] args)&&&&&&&&{&&&&&&&&&& Timer t = new Timer(new TimerCallback(ShowTime),null,0,500);&&&&&&&&&& System.Threading.Thread.Sleep(1000);& //新增&&&&&&&&&& Thread gc = new Thread(new ThreadStart(GcCollect));//新增&&&&&&&&&& gc.Start();& //新增&&&&&&&&&& Console.ReadLine();&&&&&&&&}&&&&&&&&private static void ShowTime(Object o)&&&&&&&&{&&&&&&&&&&&&Console.WriteLine(DateTime.Now.ToString());&&&&&&&&}&&&&&&&&private static void GcCollect()& //新增&&&&&&&&{&&&&&&&&&&&&GC.Collect();&&&&&&&&}&&&&}
&& 这段代码中,我虽没有在ShowTime中进行GC,但另一个线程的CoCollect函数却调用了GC.Collect,这会迫使CLR进行Garbage Collect。t只是存活了一小会儿,仍旧被回收了。
&& 但若使用方法1,上面这段代码在Release版本中仍能正常工作。
&& 后记,Garbage Colletion是一个似乎很神秘的东西。因为时常我们并不知道什么时候CLR进行Carbage Collect.以前常常将.net程序性能不好的原因都"嫁祸"在GC的头上,其实这是片面的。真正的原因是我们不了解GC,不了解GC的工作原理。
Jerry.Chow
&&&& 12/7'07
阅读(3235) | 评论(1) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
文明上网,理性发言...这样看来,有些代码需要重新改才行了。否则很杯具!!!
请登录后评论。31848人阅读
C/C++(29)
&&&&& vs中的程序有debug和release两个版本,Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发 人员提供强大的应用程序调试能力。而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。所以不保存调试信 息,同时,它往往进行了各种优化,以期达到代码最小和速度最优。为用户的使用提供便利。
&&&&&& debug程序通常比release程序要慢,尤其是处理视频方便release要比debug快很多。在release模式对程序进行调试的时候经常会遇到变量虽然初始化了,但是在查看其值的时候却发现是一个随机的数并不是初始化的值,有时候在对变量进行监视的时候了,会出现找不到变量的情况,原因大致如下:
&&&& debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc, 而release的赋值近似于随机。如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成其他变量的不准确而引起其他的错误。所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了你找都没地方找。代码存在错误在debug方式下可能会忽略而不被察觉到。debug方式下数组越界也大多不会出错,在release中就暴露出来了,这个找起来就比较难了。
&& 只有DEBUG版的程序才能设置断点、单步执行、使用 TRACE/ASSERT等调试输出语句。REALEASE不包含任何调试信息,所以体积小、运行速度快。
主要参考:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:467567次
积分:4765
积分:4765
排名:第5284名
原创:61篇
转载:81篇
评论:73条
(2)(1)(4)(1)(3)(5)(10)(4)(5)(6)(4)(7)(10)(32)(48)欢迎加入我们,一同切磋技术。 &
用户名: &&&
密 码: &
共有 2537 人关注过本帖
标题:请问Release和Debug的主要区别和用途
等 级:新手上路
帖 子:1128
&&问题点数:0&&回复次数:6&&&
请问Release和Debug的主要区别和用途
在.net下可以同时生成这2个但是我感觉差不多啊他们有什么区别各自用途又是什么呢想请明白的讲解一下相关知识
搜索更多相关主题的帖子:
等 级:新手上路
帖 子:4052
release不能调试,不能解决出现异常的情况,debug是调试用的!你在VC++.NET下用这两种模式生成的文件的大小明显不同
http://xupeng.bc-cn.net
等 级:ID已被封
帖 子:3922
一大一包含debug信息
一不包含一能用trace assert
一只能用assert
[url=javascript:alert(1);]
[div]fdgfdgfdg\"
on\"[/div]
等 级:新手上路
帖 子:928
Release版本是最终的发布版本,编译后去掉了程序中所有的注释及调试信息,因此体积也就小一些,运行效率要高一些。
public class 人生历程 extends Thread{public void run(){while(true){努力,努力,再努力!!;Thread.sleep(0);}}}
等 级:新手上路
帖 子:1128
去除注释我明白去除调试信息不大明白给个例子什么样的信息算做调试信息呀~
此号自封于日
等 级:新手上路
帖 子:1128
我想问一下大家平常用的try{}catch(){}finally{}比如这样的结构在发布的时候会被去掉吗这个结构用起来挺好啊因为比如我用一种算法处理字符串如果转换格式不对的话会出现异常这样捕获到之后就在catch里处理直接返回原来的串checked unchecked等等
此号自封于日
等 级:ID已被封
帖 子:3922
誰有詳細的兩個版本的文檔正好學習一下
[url=javascript:alert(1);]
[div]fdgfdgfdg\"
on\"[/div]
版权所有,并保留所有权利。
Powered by , Processed in 0.059608 second(s), 8 queries.
Copyright&, BCCN.NET, All Rights Reserved}

我要回帖

更多关于 vs debug release 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信