Aleksandar • Vacić

iOS bits and pieces

RS.GetRows() considered harmful

Most of my professional work is done in ASP. And with ASP I built or helped build lots of different sites, including enterprise-level ones, where web server is constantly hit - like always has 300+ requests waiting with max possible number of requests executing. Over time, I followed what was being considered best practice and implemented these things.

One of those practices, probably the most outspoken is: use [GetRows()]( method of ADODB.Recordset and then work with created 2D array. It is quicker, faster, consumes less memory - more efficient in any way. I could not find a single trace of warning, no side-effects mentioned, nothing.

Thus in the latest project I do, I went all-GetRows. I eliminated all traces of RS.EOF and RS.MoveNext, and built huge amount of code using this technique. Initial testing showed greatly increased performances (3x and more) and it went live.

Soon after, the hellish weeks started.

What no one told you is that using GetRows heavily (and I mean heavily) fragments heap memory. So much, that after some time Oracle OLEDb provider or ADO (have no idea which) starts throwing cannot allocate memory messages with several garbage characters after it. When it will happen depends on how much users are attacking the web site. The more users - the very situation where you need high code speed - the quicker it spends the memory. I guess that after a while it gets into situation where there is no large enough memory block to read recordset into it and/or create an array out of it.

CPU is always close to 100% due to heavy load. Maybe there is no free CPU time at all for memory management…

I’m totally stumped with this and have no idea what to do with it. I spent weeks rearranging the code to minimize the array allocation and only managed to postpone the problem point.

Have anyone built ASP site that gets constantly hit and uses GetRows() or generally uses lots of large arrays? Have anyone encountered this at all?

Moving to .NET is not an option in anything that resembles near future. I’m stuck with this and must solve it somehow; the only option I see now is to return to Recordset processing.