ADO ships single-threaded to protect the single-thread Microsoft Access database used by the sample site that ships with IIS. If your Web application is using ADO against Microsoft SQL Server or Oracle, you need to make ADO multithreaded. To do so, double-click the adofre15.reg file, which is part of the default ADO installation and resides in the same directory as the ADO files (e.g., \Program Files\Common Files\System\ADO on your server). The adofre15.reg file is a registry file that rewrites the threading properties of the ADO objects that reside in the registry.
High Thread Counts
Generally, a high thread count means that too many threads are running on your machine. Your processor is spending too much time managing threads and doesn't have time to serve pages. One cause of high thread counts is setting PoolThreadLimit, ASP Processor Threads, or MaxThreadPool too high for your hardware/software configuration in an attempt to increase performance. A high thread count can also occur when administrators attempt to combat threading problems by deploying a single-threaded COM object within Microsoft Transaction Server (MTS), which creates a separate thread for every instance of the object.
By reducing the number of running threads on the machine, you can keep the Context Switches/sec counter below an average value of 10,000. The counter can go above 10,000, but the average needs to stay below 10,000.
Leaks and Runaways
To fix problems involving memory leaks and runaway threads, you need to determine which Web site is causing problems. Doing so is relatively easy in IIS 5.0. You can run any Web site inside or outside the inetinfo.exe process, and to identify a problematic Web site, you need to set all your Web sites to run outside the process. In IIS Manager, right-click each Web site, choose Properties, and select the Home Directory tab, which Figure 1 shows. In the Application Protection drop-down list, select High (Isolated). Let each Web site run until Performance Monitor signals a memory leak or 100 percent CPU utilization. Doing so isolates your Web sites into separate processes.
To determine which process is leaking memory or overusing the CPU, open Task Manager on the Web server and go to the Processes tab, which Figure 2 shows. Sort the processes by Image Name and find all instances of DLLHOST.EXE. Determine which instance is using all the memory or the highest percentage of CPU time and record the process's process identifier (PID). Now that you know which process is experiencing problems, you need to figure out which Web site this process represents. Open Component Services manager from the Administrative Tools menu, then navigate the folder tree to Computers, My Computer, COM+ Applications. Right-click the node and choose Details to see all the applications' PIDs. Find your Web site in the list.
Now that you know the Web site, you can track down the component, object, or executable that's causing the problem. The cause of memory leaks and runaway-thread problems will be a COM object, ISAPI extension, or ISAPI filter. Your first step is to remove all third-party ISAPI filters and run your site for a fixed duration. If the site remains stable, add the ISAPI filters back one at a time until you discover the problematic filter. If none of the ISAPI filters are problematic, make a list of all third-party COM objects and the pages from which they're called. Use a stress-testing tool to call those pages repeatedly and determine whether the problem occurs more quickly with the tool than under typical Web traffic. If you have two COM objects on the same page, you can separate them into two testing pages and use the stress-testing method to identify the problematic page. A good free stress-testing utility is the Microsoft Web Application Stress (WAS) tool, which you can download from http://webtool.rte.microsoft.com. After you identify the problematic page, you know which COM object is causing trouble.
Bad Requests
If you don't have a memory leak or runaway-thread problem, you probably have a bad incoming request. When your server crashes, take a look at your IIS log files to determine which request caused the problem. For example, did the requested page call a COM object and were the parameters in the request's query string invalid, too long, not present, or outside the design scope? Poorly written COM objects can cause your Web server to crash, and a common bad habit of developers is failing to evaluate the input to the COM methods or properties before processing that input.
Another tool you can use to find bad incoming requests is IISTracer (available at http://iis-asp-script-real-time-monitor-tracer.pstruh.cz/help/iistrace/iis-monitor.asp), a simple ISAPI filter that displays the requests that the IIS server is handling. IISTracer uses a Web interface to display statistics about the incoming request. Determine which request is bad, then either use code, an ISAPI filter, or a service pack to prevent requests of the same type.
Still Have Problems?
If you still have stability problems after removing all third-party COM objects, ISAPI filters, and ISAPI extensions and are just calling files with ASP code, search the Microsoft Knowledge Base for articles that discuss the problems you're experiencing. Also, be sure to upgrade to the most recent service pack and examine other software (e.g., SQL Server, load-balancing software) that's not directly part of your site but that supports or affects your site. For example, antivirus and replication software can cause stability problems, as can out-of-date Oracle ODBC drivers. For information about a valuable troubleshooting tool that's built in to IIS, see the Web-exclusive sidebar "IIS Reset," http://www.windowswebsolutions.com, InstantDoc ID 25621.
Although Windows .NET Server (Win.NET Server), DNA, or n-tier COM objectdependent architectures are easy to implement, they're difficult to implement correctly. Continue to stress test and improve your COM objects, ASP code, and ISAPI extensions, and keep an eye out for memory leaks or better thread-handling methods.