My thoughts regarding ASP.NET, C#, programming practices, and more...
reading
You Should Read archives
blogs I read
|
Friday, December 17, 2004Blogs I Read
Finally got around to adding a list of links to blogs that I frequent. You can see them in the left hand nav bar of the site.
Wednesday, December 15, 2004w3wp.exe Allocating Over 1Gig of Memory
The organization I am working for has created a website that uses Microsoft's Pet Shop website as their coding model, and dynamically served up content, but cached each page by content ID. The site appears to be working well. It is hosted on a Windows 2003 server with 2 Gigs of RAM. It was built using Visual Studio .NET 2005 and us running under the .NET
Framework 2.0 Beta The Issue : When we surf the website we see a wswp.exe startup and the memory allocated to this worker process continues to climb as more and more people access the site. This would appear to be a normal thing, but this memory is not noticably released. To give you an example, we ran a test using WAPT. We had 100 users access the site 5 seconds appart, with a delay of 7 seconds on each page they accessed. We ran this for about 20 mins, and the w3wp.exe allocated about 1.1 gig of RAM. This seems like a bad thing, but not out of the norm. We ran a similar test using a very vanilla asp.net site, and the memory allocation for the w3wp.exe went up more slowly, but did not get released. I ran CLR Profiler against the new corporate website, and found what would appear to be a small memory leak that we eliminated. System.String is allocating around 25% - 30% according to the Objects By Address portion of the CLR Profiler report, but this seems to be the norm, comparing it to the same CLR Profiler report for the vanilla website mentioned above. Looking at the Objects By Address report, very little is surviving to gen 2, so I think we can eliminate memory leads. We are not appear to be doing any string concatination without using StringBuilder. My Question : Is this the norm? Have you experienced similar results? What has been your solution. Are Application Pools the answer? If so, what should the settings be? Is their a document that would help us in adjusting the settings? Sunday, December 12, 2004Check For Expired Cookies in OnInit
I am using a session state to store a UserID. I am initializing the value after the user logs in via Forms Authentication. Once logged in this UserID is stored in a session variable which I access throughout the site. This method worked fine until I started debugging. Whenever I compiled the site, the session state would be lost along with all of the session variables, setting the UserID to null.
Content copyright ©2003-2006 Tod Birdsall
Using Forms Authentication sets an authentication cookie that does not expire after a re-compile of the project. I would not be forwarded to the login page. But the page I was in would complain that the session variable was null. I would then have to go back to the login page and re-login so the UserID session variable would be initialized again. As you can imagine, this can get really annoying fast. From an end user's perspective it was even worse. If the session expired, the user would be confused by an error message indicating that their session timed out, and once again, would not be prompted to re-login. The Solution To solve this problem for the end users and make debugging less painful for me, I would check if the UserID session variable had expired before processing the rest of the page. If the variable had expired, I would forward the user to a page that would tell them in plain english that their session had expired and request that they login again. I decided to add the null session variable check to a User Control that was registered on all of the affected pages. I initially added the check for the session variable to the PageLoad event handler. Like so: I compiled the application and logged in. After re-compiling the application I clicked the refresh button on my browser, fully expecting to be redirected to the appropriate page after failing the null session check. Instead, I received the same ugly error message telling me that the session variable I was requesting in the .aspx page was null. Duh! I already knew that. OK, what could be the problem? I decided to put a break point on the Session request in both the .aspx page and the registered user control. Both requests were occurring during the PageLoad event handler, but I had a hunch that the .aspx page's PageLoad event was firing before the User Control's. I pushed F5. I then clicked the "Refresh" button on the browser. Sure enough, the .aspx pages PageLoad event was firing before the User Control's PageLoad event would fire. How can I get around this? I decided to try and find a User Control Event that fired before the PageLoad event, but far enough along in process that I could access the Session variables. I Googled and found a helpful article by Paul Wilson over at ASP Alliance titled Page Events : Order and Postback. The article explained, in the author's own words, "the complete lifecycle of ASP.NET Pages, including the postback sequence, and Perfect! I was able to determine that the OnInit Event is where I should be. It fires before the PageLoad event, and allows me to access the Session Variables. I added the appropriate code to the existing OnInit event handler, like so: override protected void OnInit(EventArgs e) Works great! Can anyone think of a better way of handling this scenario? |