Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 Other Forums
 Other Topics
 Tracking down ASP memory leak?

Author  Topic 

aiken
Aged Yak Warrior

525 Posts

Posted - 2002-04-30 : 12:33:58
Ok, it's not SQL, but I know many of you use SQL with an ASP front end.

I've got a real problem: a 250 page, 75,000 lines-of-code application that has begun to leak memory. I've definitely narrowed it down to this application. The leak is fairly slow -- maybe 20MB/hour, but that adds up, and the server has to be rebooted nightly.

I found one frequently used page that was not closing or freeing its recordsets; fixing that slowed the leak from 50MB/hour to 20MB/hour. But not I've got to track that down.

Is there any way to find what page(s) are causing the leak? Any ideas other than not closing recordsets that might cause it (and why would that cause it, anyways? Doesn't ASP garbage collect after the page completes?).

Thanks for any advice
-b

MichaelP
Jedi Yak

2489 Posts

Posted - 2002-04-30 : 12:46:39
Are you using any COM objects with your ASP pages? If so, what language are they written in? Do they use ADO?

COM objects are usually the cause of memory leaks in my experience. ASP pages clean up after themselfs "in theory." I think they generally do, but they are not perfect from what I've been seeing. It's a best practice to kill all of your objects yourself instead of letting garbage collection handle it.

Michael

Go to Top of Page

AjarnMark
SQL Slashing Gunting Master

3246 Posts

Posted - 2002-04-30 : 12:57:25
If you want to search for pages that are not properly closing and destroying their objects, you might want to look at this Search and Replace utility from Funduc Software. I find it really handy, and it has some ability to be scripted.

Maybe a wild idea, but I'm thinking you could create a list of all your ASP pages, perhaps just a DIR into a text file. Then use SR to search on Close or Nothing (assuming you have some standard naming for your Recordset, Command and Connection objects makes this easier). And then wrapup with a Windiff between the two lists.

Maybe I'm dreaming, but it's an idea...

Go to Top of Page

aiken
Aged Yak Warrior

525 Posts

Posted - 2002-04-30 : 13:43:35
Thanks for the ideas.

The pages use two commercial COM objects... I'm testing now to see if I can isolate the problem to one of them, but I doubt it (they're both fairly popular components that are used on higher volume sites).

I'm not sure the windiff idea is going to work for me; the pages are all fairly large, many of them over 1500 lines of code. I can pretty much guarantee that every page has at least a couple of recordset opens and closes.... I think the problem is that some conditional situations may let the page end processing without destroying its objects. Something like:


Set oRS=Server.CreateObject("ADODB.RecordSet")
oRS.Open "select 1"....
.
.
.
If bSomecondition then
Response.Redirect("http://somewhere_else")
End If
.
.
.
oRS.Close
Set oRS=nothing


...at least, that's my best guess so far. It would really help if I could tell what pages are leaking, though... going through 250 or so pages just eyeballing them for problems is going to take forever.

Thanks!
-b

--sorry, did an edit 'cause it wasn't displaying correctly.

Edited by - robvolk on 04/30/2002 17:05:05
Go to Top of Page

Merkin
Funky Drop Bear Fearing SQL Dude!

4970 Posts

Posted - 2002-04-30 : 19:25:39
Yep that will do it for sure.

You have to close objects before you redirect. There are a few articles around ASPAlliance.com from memory, they discuss this and suggest using a subroutine for redirects.

When it is called, it destroys any open recordsets and your connection, (assuming you stick to set names for objects).

Either than, or you can have the fun of closing all your recordsets manually for 750 asp pages....



Damian
Go to Top of Page

royv
Constraint Violating Yak Guru

455 Posts

Posted - 2002-04-30 : 19:31:51
ASP pages do garbage collection upon page completion, but there are problems with some objects in ASP. If you are using the Session object, then it will leak memory, there is nothing you can do about it, its a problem with the ASP engine. If I am not mistaken, I also believe that there are threading issues also involved with ASP, so if your COM is in C++ and its multi-threaded, you might run into some problems there as well.

HTH

*************************
Just trying to get things done
Go to Top of Page

Merkin
Funky Drop Bear Fearing SQL Dude!

4970 Posts

Posted - 2002-04-30 : 19:48:03
quote:


ASP pages do garbage collection upon page completion




In theory.
The reality is that if you don't close your recordsets and connections you will run into these problems.

Damian
Go to Top of Page

rrb
SQLTeam Poet Laureate

1479 Posts

Posted - 2002-04-30 : 21:35:05
My attitude is always (with respect to recordsets) get in and get out ASAP. I generally try to avoid having the recordset open for any longer than I absolutely have to - even in some cases where this means loading data from my recordsets into arrays - (only small ones though), or closing and reopening.

However, I can afford the additional hit...BTW, Access has exactly the same issue - if you don't set your objects = Nothing by the time your code finishes, watch your memory go... (I found out the hard way).

cheers

Edited by - rrb on 04/30/2002 21:36:38
Go to Top of Page

aiken
Aged Yak Warrior

525 Posts

Posted - 2002-05-02 : 02:29:10
I totally agree with everything that's been said here. I'd be very interested if anyone can post, or post a link to, a sub that will check a DB connection for open recordsets, close and nothing them, then close the DB connection. Google hasn't turned anything up for me.

However, I'd be even more interested in any way to find out *which pages* are leaking. I did a quick check and found that there are about 160 redirects in my application, spread accross 50 pages or so. I can go through them one by one, of course, but that's not terribly efficient. Worse, the problem may not even be a redirect; it could be something else entirely.

Is there really no way to tell which ASP pages are allocating/deallocating memory?

Cheers
-b

Go to Top of Page

Merkin
Funky Drop Bear Fearing SQL Dude!

4970 Posts

Posted - 2002-05-02 : 02:52:00
Hi

I don't think there is a way of finding out about individual pages.

Here is the article I was talking about though, http://www.aspalliance.com/bbilbro/DesktopDefault.aspx?tabindex=1&tabid=7&ArticleID=2

A technique like this will only work if you know what all your objects are called.

I would suggest spending a few hours with a good editior, doing a search on all instances of response.redirect and cleaning up the code. It will be worth it in the long run.

Damian
Go to Top of Page

royv
Constraint Violating Yak Guru

455 Posts

Posted - 2002-05-02 : 09:41:08
Thanks for the correction Merkin, you are correct, in theory ASP should clean up everything, but as we all know it has problems with that concept. Anyway, response.redirects are expensive, so this is an avenue worth checking. We had a similar problem and we had to re-write the app, so I'm in total agreement with Merkin that the time and effort needs to spent in cleaning up the code.

*************************
Just trying to get things done
Go to Top of Page

AjarnMark
SQL Slashing Gunting Master

3246 Posts

Posted - 2002-05-02 : 13:05:16
If your pages are stored in multiple subdirectories, you could go into IIS Admin and set each of these directories as applications or packages (whatever they call them) and set them to run in High Isolation. This will put each of them into their own .exe and you can run some processes to see which of those exe's is eating up memory and then look at the pages for that exe. I don't know how our server team did the last part, but they somehow were able to figure out which exe represented which pages.

That's about the only way I can think of that you might be able to narrow down your search. Otherwise, it's one at a time...

Good luck!

Go to Top of Page

aiken
Aged Yak Warrior

525 Posts

Posted - 2002-05-03 : 01:02:14
Thanks for all of the help. That link is perfect, Merkin. I'll be implementing the redirect code from there shortly.

Unfortunately, most of the app is in one directory. I suppose, if the redirect fix doesn't help, I could move bits of it around and do the high isolation thing to test one page at a time. No fun at all, though.

Cheers
-b

Go to Top of Page

aiken
Aged Yak Warrior

525 Posts

Posted - 2002-05-05 : 21:16:16
Well, here's an update.

I've implemented the sub for redirect throughout the entire application. Just to be safe, that sub goes beyond what was suggested in the link and does a series of "If IsObject"'s on every name for an ADO or other object used in the application.

The leak may have slowed some, but it's still there and going strong. Worse, examinging 24 and 48 hour traces from perfmon, the app is experiencing times of 3-4 hours with no leak at all, then 3-4 hours of steadily declining available memory. So far, I can't find any correlation to usage statistics or anything else.

I'm really not sure where to go from here -- I doubt it's an ASP or IIE or W2K leak, so it's almost certainly in my app. But where?

Damn, I wish there was a way to see how how much memory is allocated for each type of object, so I could see if I'm piling up recordsets or some other object. Or that there was a way to see how much memory is being used by each page in the application. "Somewhere in 75,000 lines of code" is not a lot to go on.

Argh. Any more thoughts?

Cheers
-b

Go to Top of Page

Merkin
Funky Drop Bear Fearing SQL Dude!

4970 Posts

Posted - 2002-05-05 : 21:53:18
ASP is fun like that isnt it

One suggestion, upgrade your MDACs if you haven't already. I have seen all sorts of problems fixed by updating that.

Other than that, it is a bit hard to guess.

Damian
Go to Top of Page

aiken
Aged Yak Warrior

525 Posts

Posted - 2002-05-07 : 13:25:32
Well, updating from MDAC 2.6SP1 to MDAC 2.7 has either eliminated the problem, or at least slowed it so drastically that it's a nonissue. The servers used to need rebooting every 18 hours; if the leak is there at all, we're on track for at least 21 days of uptime, which is fine by me.

The good news: this made me go through and improve the code, fix all of the redirects, fix numerous places where recordsets were improperly closed, and generally do a code review and fix egregious problems.

The aggravating news: all of that work didn't really have a material effect. Apparently, the biggest issues were in MDAC, not my app.

Cheers, and thanks to everyone who helped.

-b

Go to Top of Page
   

- Advertisement -