EyeContact
asked on
Memory leak
Hello all,
I'm running IIS 6.0 on Win2K3.
The script below pulls an image out of my (Access) database, I use the asppainter object to set the quality and then I use the binarywrite method to send it to the client's browser. After I run it, the memory usage of the w3wp.exe process increases with about 300KB and it doesn't decrease again. Since this page is called in a loop to display a lot of images the memory increases very fast.
<!--#include file="../../parameters.asp "-->
<%
DIM bdata
DIM mypic
STILLID = Request.Querystring("STILL ID")
SQL_STRING = "select STILLDATA from STILLS WHERE STILLID="&STILLID&";"
DSN_CONN_STRING=dbkoppelin g()
set DB_CONN=server.createobjec t("ADODB.C onnection" )
DB_CONN.Open DSN_CONN_STRING
Set RS = Server.CreateObject("ADODB .Recordset ")
RS.Open SQL_STRING, DB_CONN, adOpenStatic, adLockOptimistic, adCmdText
If Not RS.EOF Then
If Not IsNull(RS("STILLDATA")) Then
Set pic = CreateObject("ASPPainter.P ictures.1" )
mypic = RS("STILLDATA")
pic.LoadStream (mypic)
pic.SetJpegQuality 50
pic.SetFormat 1
bdata = pic.SaveToStream
Response.ContentType = "image/jpeg"
Response.BinaryWrite bdata
mypic = ""
bdata = ""
pic.Destroy
pic.DestroyALL
Set pic=Nothing
Set mypic = Nothing
Set bdata = Nothing
End If
End If
RS.Close
Set RS = Nothing
DB_CONN.Close
Set DB_CONN=Nothing
%>
Any ideas?
I'm running IIS 6.0 on Win2K3.
The script below pulls an image out of my (Access) database, I use the asppainter object to set the quality and then I use the binarywrite method to send it to the client's browser. After I run it, the memory usage of the w3wp.exe process increases with about 300KB and it doesn't decrease again. Since this page is called in a loop to display a lot of images the memory increases very fast.
<!--#include file="../../parameters.asp
<%
DIM bdata
DIM mypic
STILLID = Request.Querystring("STILL
SQL_STRING = "select STILLDATA from STILLS WHERE STILLID="&STILLID&";"
DSN_CONN_STRING=dbkoppelin
set DB_CONN=server.createobjec
DB_CONN.Open DSN_CONN_STRING
Set RS = Server.CreateObject("ADODB
RS.Open SQL_STRING, DB_CONN, adOpenStatic, adLockOptimistic, adCmdText
If Not RS.EOF Then
If Not IsNull(RS("STILLDATA")) Then
Set pic = CreateObject("ASPPainter.P
mypic = RS("STILLDATA")
pic.LoadStream (mypic)
pic.SetJpegQuality 50
pic.SetFormat 1
bdata = pic.SaveToStream
Response.ContentType = "image/jpeg"
Response.BinaryWrite bdata
mypic = ""
bdata = ""
pic.Destroy
pic.DestroyALL
Set pic=Nothing
Set mypic = Nothing
Set bdata = Nothing
End If
End If
RS.Close
Set RS = Nothing
DB_CONN.Close
Set DB_CONN=Nothing
%>
Any ideas?
ASKER
Hi Ajai,
I have no idea how to do that.
Why are you suggesting this? If this can be done in plain and simple asp, why would I need to make a dll?
EC.
I have no idea how to do that.
Why are you suggesting this? If this can be done in plain and simple asp, why would I need to make a dll?
EC.
One very simple thing to try (which I doubt will make alot of difference) is to turn buffering off. That means that binary data will be sent to the client immediately rather than when the whole page has finished executing. Just add this line at the top of your page:
Response.Buffer = false
Secondly, I wouldn't do this:
bdata = pic.SaveToStream
Response.BinaryWrite bdata
because you're copying the binary data into another variable before writing it out to the browser. This is completely unnecessary and only increases memory usage. Just use:
Response.BinaryWrite pic.SaveToStream
And one more thing: do you absolutely have to use the image component? All you're doing is setting the image quality. I guess you're doing this to make the output images smaller. Fair enough. But again, this only increases memory usage on your server. The absolute best option in terms of performance would be to write the binary data directly to the client from the database and bypass the image component altogether.
And getting a bit off topic...
You'll no doubt get lots of people asking you why you store the image data in a DB table rather than as a file on the file system. And this is good question :-) Do you really need to do this? This will make your DB grow enormously which with Access in particular is never a good thing.
Response.Buffer = false
Secondly, I wouldn't do this:
bdata = pic.SaveToStream
Response.BinaryWrite bdata
because you're copying the binary data into another variable before writing it out to the browser. This is completely unnecessary and only increases memory usage. Just use:
Response.BinaryWrite pic.SaveToStream
And one more thing: do you absolutely have to use the image component? All you're doing is setting the image quality. I guess you're doing this to make the output images smaller. Fair enough. But again, this only increases memory usage on your server. The absolute best option in terms of performance would be to write the binary data directly to the client from the database and bypass the image component altogether.
And getting a bit off topic...
You'll no doubt get lots of people asking you why you store the image data in a DB table rather than as a file on the file system. And this is good question :-) Do you really need to do this? This will make your DB grow enormously which with Access in particular is never a good thing.
ASKER
Hello deighc,
Thanks a lot for your detailed description. Based on your advise I did some further testing and I found out that it is indeed the asppainter component that is causing the memory leak.
I'll tell you a little more of what I am doing here.
Users are uploading powerpoint presentations into my web application. I save the slides as TIF images in the database. Then on the next page, the user gets an overview of all slides (this is the part described above) and he can set times for each slide. The last step is to create an MPEG movie from the TIF images. After that the images will usually be deleted by the user from the database (unless he's not happy with the result (timing..) then he can make a new MPEG).
The TIF files are obviously too big to send to the client, therefor I'm using the asppainter component to make the page load time acceptable.
I will contact the creator of the component and see if he/they know how to fix the leak.
If not, can you advise me another component or workaround?
EC.
Thanks a lot for your detailed description. Based on your advise I did some further testing and I found out that it is indeed the asppainter component that is causing the memory leak.
I'll tell you a little more of what I am doing here.
Users are uploading powerpoint presentations into my web application. I save the slides as TIF images in the database. Then on the next page, the user gets an overview of all slides (this is the part described above) and he can set times for each slide. The last step is to create an MPEG movie from the TIF images. After that the images will usually be deleted by the user from the database (unless he's not happy with the result (timing..) then he can make a new MPEG).
The TIF files are obviously too big to send to the client, therefor I'm using the asppainter component to make the page load time acceptable.
I will contact the creator of the component and see if he/they know how to fix the leak.
If not, can you advise me another component or workaround?
EC.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
We didn't really solve the problem, but you took your time to help me so I accepted your answer. I emailed the asppainter guys and I hope to get a response from them soon.
EC.
EC.
Try to convert these code inside an VB dll and run it as component services.
Bye
Ajai