ASP.NET Memory:如果你的应用已经在生产环境中,那为什么还要debug=true
Posted on 2008-05-27 18:13 互联网粒子 阅读(274) 评论(0) 编辑 收藏 举报
问题陈述:
确保在每个asp.net 应用中web.config里面在<compilation>节中的“debug=false”。这个在开发中的缺省设置是true,而且他是我们经常的犯的错误,把这个缺省设置部署到在生产环境中的实际应用。你没有必要设置为true,因为它会导致内存的总开销和低效率。
保留debug=true会导致什么问题?
当设置为true或者false,主要有3个主要的差别
1) asp.net 过期时间
2) 批量编译
3) 代码优化
asp.net 过期时间
当设置为debug=true时,asp.net 请求不会过期,这个会允许你用vs studio来按照你自己的步调来调式程序而不用担心这个请求会突然消失。当然,在生产环境中,超时过期是确保请求不会被卡住,这就是针对第一个的理由。
批量编译
简单来说,当设置为true,我们不会进行批量编译,而false 则会。
这是什么意思?
当一个 aspx、asax、ascx页面第一次被请求,它会被编译成一个dll程序集。这个程序集有一个类似3ks0rnwz.dll的名字(8个字符),里面保存的是实际的ascx、asax或aspx的类(不是code behind 的代码),这个文件在C:\WINDOWS\Microsoft.NET\Framework\版本\Temporary ASP.NET Files文件夹的应用程序名下面。
那些code behind的类被编译到程序集的主dll中,他和其他的dll一起放在应用程序的bin目录下,拷贝映射到asp.net 临时目录。
回到3ks0rnwz.dll… 如果我们把debug设置为true,那么会为每个aspx、asax或ascx页面创建一个dll,而且是debug模式的dll,所以如果你有100个页面,那会创建100个程序集,他们会在页面被请求的时候创建。
如果我们把debug设置为false,那会批量编译。意思是第一次请求任何页面的时候,会编译整个应用程序,生成一个很大的dll,这是一个事实,但有些修正,用户控件(ascx页面)会被编译成到一个分开的程序集中,和aspx页面分离,而aspx页面会分组按他们所引用的用户控件分组编译,global.asax也是分开编译。编译也是基于目录的,即如果应用中还有子目录,那子目录也是单独编译,避免同名冲突,因为在可能有相同名字的aspx页面在不同的目录中。但总的来说,相比100个dll,你肯那个只有4 或5个dll。
因为代码都是相同的,所以合在一起的dll合单独的dll的大小并没有很大的差别,但那有一个很大的…总体消耗,对每个dll而言。在dubug模式下编译的dll有一个为了调试而需要的资源消耗。最重要的是,这些dll不会在内存中一个挨着一个排列着,所以,针对有很多的dll的情况,你会开始在虚拟内存中搞出碎片,这将会更难的找到足够的空间来存储托管堆,很有可能会导致内存异常。
另一种情况是,如果设置debug=false,你修改了一个aspx页面,这个页面就需要重新编译,但这不会导致应用程序域(appdomain)重新加载,这样整个程序就不会重新批量编译,单个页面会被单独编译,生成一个dll。所以不要在一个运行着的服务器上经常行的改变你的aspx页面。
在machine.config中有一个配置选项,允许重新编译多少个页面而应用程序域不重启动。缺省的是15,所以在有15个重新编译行为之后,应用程序域会重新启动,这个跟你修改web.config 或bin目录导致应用程序域重启一样。
代码优化
JIT为了能够单步的调试代码,并不能够真的优化代码,所以debug模式下的代码性能就会比release模式的要差。
如何在内存dump文件找出这些?
要确定你的应用程序时候运行在debug模式下,在sos.dll中有一个很灵巧的命令是 !finddebugtrue,它会列出你需要的信息。
0:016> !finddebugtrue
Debug set to true for Runtime: 61b48dc, AppDomain: /MyDebugApplication
Debug set to true for Runtime: 1f50e6d8, AppDomain: /MemoryIssues
Total 16 HttpRuntime objects
要找出你忘记编译成release模式的模块,你可以运行 !finddebugmodules
0:016> !finddebugmodules
Loading all modules.
Searching for modules built in debug mode...
MyDebugApplication.dll built debug
MemoryIssues.dll built debug
fl4sq-9i.dll built debug
wepr1t3k.dll built debug
r9ocxl4m.dll built debug
zmaozzfb.dll built debug
Done Seaching
那些8个字母的dll是JIT引擎编译的aspx页面。
噢,前面我忘记了….当你从debug=true改变到debug=false时,把 asp.net 临时目录里的程序集删除掉,这样你不会有那些导致不会批量编译的旧垃圾。
在asp.net 2.0中,在machine.config中有一个开关量,可以吧debug=true 关闭,所有有了他,你不必担心那个应用程序是debug模式或不是。
<configuration>
<system.web>
<deployment retail=”true”/>
</system.web>
</configuration>
确保在每个asp.net 应用中web.config里面在<compilation>节中的“debug=false”。这个在开发中的缺省设置是true,而且他是我们经常的犯的错误,把这个缺省设置部署到在生产环境中的实际应用。你没有必要设置为true,因为它会导致内存的总开销和低效率。
保留debug=true会导致什么问题?
当设置为true或者false,主要有3个主要的差别
1) asp.net 过期时间
2) 批量编译
3) 代码优化
asp.net 过期时间
当设置为debug=true时,asp.net 请求不会过期,这个会允许你用vs studio来按照你自己的步调来调式程序而不用担心这个请求会突然消失。当然,在生产环境中,超时过期是确保请求不会被卡住,这就是针对第一个的理由。
批量编译
简单来说,当设置为true,我们不会进行批量编译,而false 则会。
这是什么意思?
当一个 aspx、asax、ascx页面第一次被请求,它会被编译成一个dll程序集。这个程序集有一个类似3ks0rnwz.dll的名字(8个字符),里面保存的是实际的ascx、asax或aspx的类(不是code behind 的代码),这个文件在C:\WINDOWS\Microsoft.NET\Framework\版本\Temporary ASP.NET Files文件夹的应用程序名下面。
那些code behind的类被编译到程序集的主dll中,他和其他的dll一起放在应用程序的bin目录下,拷贝映射到asp.net 临时目录。
回到3ks0rnwz.dll… 如果我们把debug设置为true,那么会为每个aspx、asax或ascx页面创建一个dll,而且是debug模式的dll,所以如果你有100个页面,那会创建100个程序集,他们会在页面被请求的时候创建。
如果我们把debug设置为false,那会批量编译。意思是第一次请求任何页面的时候,会编译整个应用程序,生成一个很大的dll,这是一个事实,但有些修正,用户控件(ascx页面)会被编译成到一个分开的程序集中,和aspx页面分离,而aspx页面会分组按他们所引用的用户控件分组编译,global.asax也是分开编译。编译也是基于目录的,即如果应用中还有子目录,那子目录也是单独编译,避免同名冲突,因为在可能有相同名字的aspx页面在不同的目录中。但总的来说,相比100个dll,你肯那个只有4 或5个dll。
因为代码都是相同的,所以合在一起的dll合单独的dll的大小并没有很大的差别,但那有一个很大的…总体消耗,对每个dll而言。在dubug模式下编译的dll有一个为了调试而需要的资源消耗。最重要的是,这些dll不会在内存中一个挨着一个排列着,所以,针对有很多的dll的情况,你会开始在虚拟内存中搞出碎片,这将会更难的找到足够的空间来存储托管堆,很有可能会导致内存异常。
另一种情况是,如果设置debug=false,你修改了一个aspx页面,这个页面就需要重新编译,但这不会导致应用程序域(appdomain)重新加载,这样整个程序就不会重新批量编译,单个页面会被单独编译,生成一个dll。所以不要在一个运行着的服务器上经常行的改变你的aspx页面。
在machine.config中有一个配置选项,允许重新编译多少个页面而应用程序域不重启动。缺省的是15,所以在有15个重新编译行为之后,应用程序域会重新启动,这个跟你修改web.config 或bin目录导致应用程序域重启一样。
代码优化
JIT为了能够单步的调试代码,并不能够真的优化代码,所以debug模式下的代码性能就会比release模式的要差。
如何在内存dump文件找出这些?
要确定你的应用程序时候运行在debug模式下,在sos.dll中有一个很灵巧的命令是 !finddebugtrue,它会列出你需要的信息。
0:016> !finddebugtrue
Debug set to true for Runtime: 61b48dc, AppDomain: /MyDebugApplication
Debug set to true for Runtime: 1f50e6d8, AppDomain: /MemoryIssues
Total 16 HttpRuntime objects
要找出你忘记编译成release模式的模块,你可以运行 !finddebugmodules
0:016> !finddebugmodules
Loading all modules.
Searching for modules built in debug mode...
MyDebugApplication.dll built debug
MemoryIssues.dll built debug
fl4sq-9i.dll built debug
wepr1t3k.dll built debug
r9ocxl4m.dll built debug
zmaozzfb.dll built debug
Done Seaching
那些8个字母的dll是JIT引擎编译的aspx页面。
噢,前面我忘记了….当你从debug=true改变到debug=false时,把 asp.net 临时目录里的程序集删除掉,这样你不会有那些导致不会批量编译的旧垃圾。
在asp.net 2.0中,在machine.config中有一个开关量,可以吧debug=true 关闭,所有有了他,你不必担心那个应用程序是debug模式或不是。
<configuration>
<system.web>
<deployment retail=”true”/>
</system.web>
</configuration>