博客园 联系 订阅 订阅 管理  

Blog Stats

News


昵称:Chainet
园龄:7年7个月
粉丝:0
关注:0

收藏夹

随笔档案

相册

I'm reading

Source Code

友情链接

Chainet的技术生涯

希望有所进步

2005年1月25日 #

介绍
我所参与做的产品是一个比较大型的ASP.NET系统,在测试部门和客户那里,如果长时间运行,
系统常常会出现一些OutOfMemoryException的异常。引起内存溢出的错误的原因有很多,主要在服务器配置方面和代码编写两个方面可以进行优化和改进,避免此类问题的出现,但完全杜绝是比较困难的。下面是我收集整理的一些解决方法。 

服务器配置方面

        1.   安装.NET Framework 1.1 Service Pack 1

补丁部分解决了一些内存泄漏的问题,下载地址为:http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38 
        2.   使用更多的内存

                a.打开/3GB Switch(如果你有3GB以上的内存)。这个配置只在Windows 2000 Advanced ServerData Center版本以及Windows Server 2003以上才支持,参见:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt17.asp

http://support.microsoft.com/default.aspx?scid=kb;en-us;820108

                 b.即使你有很多内存,但.NET(注意不是ASP.NET工作进程,而是.NET整个使用的内存是有一定限制的,可以通过加大配置使用量来减少内存溢出的发生。方法如下:

修改machine.config文件,一般在 %System%\Microsoft.Net\Framework\v1.1.4322\CONFIG目录中, 修改processModel元素中的memoryLimit,大于缺省设置的60(意味着物理内存的60%)。

        3. 回收工作线程

设置IIS定期清除Work process是避免此异常的一个较好的方式。但这个功能是IIS 6.0(也就是Windows 2003上带的IIS)才支持。

配置方法如下:

修改IIS的应用程序池配置,选择DefaultAppPool(如果你的系统是用这个池),右键点属性->Recycling Setting,然后选择根据情况 修改“Recycle worker processes at the following times:'等几项配置,其中定时回收工作进程是一个比较好的方式,可以避免回收工作进程时,引起客户Session丢失。

Windows 2000 server 上安装的是IIS 5.0,本身不支持Recycle,但要想实现这个功能也不难。微软针对IIS提供的IIS5Recycle便是这样一个程序,它安装后以服务形式提供回收工作进程。

安装说明见http://support.microsoft.com/?id=322350

图片是表示安装好之后的配置信息! 是不是和IIS6中的一模一样?


代码编写方面的注意问题 

1.System.Drawing方面的类使用问题

System.Drawing用到了很多系统的资源和非托管代码,所以使用的时候要特别小心,注意内存泄漏(Memory Leak)例如:BitMap.MakeTransparent方法的使用问题:

http://www.dotnet247.com/247reference/msgs/40/202528.aspx

2.new byte[]问题

处理流的时候常常会用到new一个大的byte数组。但在多用户情况下会消耗大量的内存。正确的做法应该是定义一个比较小的byte数组做为缓存,然后循环使用。如在我们的程序中,有些地方使用不当,当图片(或附件)过大或过多的时候, new byte[length]就有可能消耗过多的内存。

3.  避免使用大对象数组或小对象大数组

编程时同样要重视效率问题(包括内存占用问题)。

4.Com接口调用是要注意释放对象。

posted @ 2005-01-25 13:37 Chainet 阅读(4690) 评论(5) 编辑

2004年8月13日 #

众所周知,Singleton模式是设计模式中比较简单和容易实现的模式之一,对此我就不详细描述其基本原理和用途,只谈谈在.NET中的实现。
MSDN中有专门一篇文章《在 C# 中实现 Singleton》对此进行描述。
其中描述了最简单的实现方式:原始代码

public sealed class Singleton 

   
private static readonly Singleton instance = new Singleton(); 
   
private Singleton(){} 
   
public static Singleton Instance 
   

      
get  
      

         
return instance;  
      }
 
   }
 
}
 

而对于静态构造函数,MSDN中是这样描述的“静态构造函数用于初始化类。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。”参见

一直以来我都不太赞同使用静态构造方法去构建Singleton模式。然而当我用反编译器反编译原始代码之后,大跌眼镜(虽然我没有眼睛),发现反编译出来代码就是用静态构造函数去初试化的。这是反编译出来的结果。
public sealed class Singleton
{
    
private static readonly Singleton instance;
    
private static Singleton()
    
{
         instance 
= new Singleton();
    }

    
private Singleton();
    
public static Singleton Instance 
    

          
get
          
{
                
return Singleton.instance;
          }

    }

    
}

因此我得出结论可以断定,C#中的静态构造函数是实现Singleton模式的。

而对于多线程的环境下,MSDN开发精选2期中对C#实现Singleton模式的文章中也明确表明,.NET framework的机制其实已经保证了用第一种方法实现的Singleton多线程安全,原因是什么呢?文章中没说。
其实就是静态构造函数
posted @ 2004-08-13 11:46 Chainet 阅读(1085) 评论(3) 编辑

2004年8月10日 #

微软今天在官方网站Downloads当中提供英文版和德文版Windows XP SP2下载,其中SP2英文版官方文件名是WindowsXP-KB835935-SP2-ENU.exe,文件大小272391KB,发布日期2004年8月9日,下载地址:
http://www.microsoft.com/downloads/details.aspx?FamilyId=049C9DBE-3B8E-4F30-8245-9E368D3CDB5A&displaylang=en

posted @ 2004-08-10 13:50 Chainet 阅读(1349) 评论(0) 编辑

2004年7月25日 #

上次因为使用Snippet Compiler,而发现 使Snippet Compiler运行在.NET Framework 2.0(beta1)下的方法.
实际上,进一步研究发现由于Microsoft在设计.NET Framework时考虑到向下兼容的问题,提供一个通用的方法——配置文件。任何程序集都可以通过配置文件来改变其运行时所采用的CLR版本,就是说1.0可以在1.1下,1.0和1.1可以运行在2.0下。
配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
     
<startup>
        
<supportedRuntime version="v2.0.40607"/>
        
<requiredRuntime version="v2.0.40607"/>
    
</startup>
    
<runtime>
      
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         
<probing privatePath="bin"/>
      
</assemblyBinding>
   
</runtime>
</configuration>

但是反过来是不是就不一定行了呢?用以下代码测试,结果是——向下兼容,向上不兼容。
using System;
public class Test
{
    
public static void Main()
    
{
        Console.WriteLine(Environment.Version);
        Console.ReadLine();
    }

}

有趣的是,如用V2.0编译的程序指定运行在v1.1下,会报下面的异常
System.BadImageFormatException
见ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfSystemBadImageFormatExceptionClassTopic.htm

这难道说V2.0编译的执行文件的格式都不一样了?
posted @ 2004-07-25 00:00 Chainet 阅读(971) 评论(2) 编辑

2004年7月19日 #

自从发现Snippet Compiler这个工具后就经常用它来做些小的代码,有IntelliSense确实比Edit Plus方便很多,另外调试Web程序也比较方便,所以Snippet Compiler基本上成为我机器里的必备工具之一。
但是,自从.NET framework 2.0出来之后,我便经常会去学习写一些2.0的代码。这时候发现Snippet Compiler不能加载.NET 2.0的程序集。不过还好作者在做的时候就考虑到这点,做了一个Config文件配置运行与不同的.net framework版本,还特地在主页上放了一个v1.0的配置文件下载。
于是我便希望修改那个配置文件以便能使其运行与v2.0下,可惜那个配置文件好像有些问题。改来改去,总是出错。最后我直接修改v1.1的配置文件,终于使它能加载v2.0(beta1)的程序集,并编译成2.0的程序。
下面是截图

下面是修改后的Config文件,希望对人有点用处。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
     
<startup>
        
<supportedRuntime version="v2.0.40607"/>
        
<requiredRuntime version="v2.0.40607"/>
    
</startup>
    
<runtime>
      
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         
<probing privatePath="bin"/>
      
</assemblyBinding>
    
<dependentAssembly>
        
<assemblyIdentity name="System" publicKeyToken="b77a5c561934e089" culture="neutral"/>
        
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="1.0.3300.0"/>
    
</dependentAssembly>
   
</runtime>

</configuration>
posted @ 2004-07-19 14:12 Chainet 阅读(1170) 评论(0) 编辑