MapServer 4.10.1 Memory Leak still exists
David Martin
david at ITBEYOND.COM.AU
Wed Apr 18 19:15:08 PDT 2007
I have been testing MS 4.10.0 and 4.10.1 and have found that the Memory
Leak issue identifed in 4.10.0 still exists in 4.10.1 when running the C#
mapserver dlls and Mapscript.
Now I am using vb.net for the code development. I have released the code
live today and found it ran for 30mins before it consumed over 1Gb of system
memory. The code I am using is as follows:
There are two subs that inerface to MS one to display images and the other
to process form data and run a query:
Private Sub DisplayImage(ByVal RefineImage As Boolean)
Dim imageLoc, RefimageLoc As String
If RefineImage Then
' This is a refined query - show number of results to the screen and
also the refined map
imageLoc = "/Uploads/iMapPlot/tmp/" & Math.Abs(Now.ToBinary)
& ".gif"
RefimageLoc = "/Uploads/iMapPlot/tmp/Ref" & Math.Abs
(Now.ToBinary) & ".gif"
MSMap = New mapObj(MapFile())
MSMap.setExtent(CurrentExtent.minx, CurrentExtent.miny,
CurrentExtent.maxx, CurrentExtent.maxy)
Dim Refineimg As imageObj
Dim Referenceimg As imageObj
If MapLayers <> "" Then
Dim layerElements As String() = Split(MapLayers, ",")
Dim layer As String
Dim lyr As layerObj
For Each layer In layerElements
lyr = MSMap.getLayerByName(layer)
lyr.status = STATUS_VALUES.MS_ON
If layer = "Places" Then
lyr.data = "..\ExplorOz\Places\" & PlacesPOIName
Dim sty As styleObj = lyr.getClass(0).getStyle(0)
sty.setSymbolByName
(MSMap, "../../Images/PointPlace/symbols/" & PlacesPOIImage & ".gif")
End If
Next
End If
Refineimg = MSMap.draw
Refineimg.save(Server.MapPath(imageLoc), Nothing)
Refineimg.Dispose()
Referenceimg = MSMap.drawReferenceMap
Referenceimg.save(Server.MapPath(RefimageLoc), Nothing)
Referenceimg.Dispose()
CurrentExtent.maxx = MSMap.extent.maxx
CurrentExtent.minx = MSMap.extent.minx
CurrentExtent.maxy = MSMap.extent.maxy
CurrentExtent.miny = MSMap.extent.miny
MSMap.Dispose()
MainMap.Src = imageLoc
refimg.Src = RefimageLoc
Else
imageLoc = "/Uploads/iMapPlot/Cache/" & Replace(Mid(MapFile,
InStrRev(MapFile, "\") + 1), ".map", "_" & Replace(MapLayers, ",", "") &
PlacesPOIName & ".gif")
RefimageLoc = "/Uploads/iMapPlot/Cache/Ref" & Replace(Mid(MapFile,
InStrRev(MapFile, "\") + 1), ".map", "_" & Replace(MapLayers, ",", "") &
PlacesPOIName & ".gif")
If Not System.IO.File.Exists(Server.MapPath(imageLoc)) Or Not
System.IO.File.Exists(Server.MapPath(RefimageLoc)) Then
Dim img As imageObj
Dim Referenceimg As imageObj
MSMap = New mapObj(MapFile())
If MapLayers <> "" Then
Dim layerElements As String() = Split(MapLayers, ",")
Dim layer As String
Dim lyr As layerObj
For Each layer In layerElements
lyr = MSMap.getLayerByName(layer)
lyr.status = STATUS_VALUES.MS_ON
If layer = "Places" Then
lyr.data = "..\ExplorOz\Places\" & PlacesPOIName
Dim sty As styleObj = lyr.getClass(0).getStyle(0)
sty.setSymbolByName
(MSMap, "../../Images/PointPlace/symbols/" & PlacesPOIImage & ".gif")
End If
Next
End If
img = MSMap.draw
img.save(Server.MapPath(imageLoc), Nothing)
img.Dispose()
Referenceimg = MSMap.drawReferenceMap
Referenceimg.save(Server.MapPath(RefimageLoc), Nothing)
Referenceimg.Dispose()
MSMap.Dispose()
End If
MainMap.Src = imageLoc
refimg.Src = RefimageLoc
End If
map.Value = MapFile()
layer.Value = MapLayers
End Sub
Private Sub Query()
Dim result As Integer
Dim lyr As layerObj
MSMap = New mapObj(MapFile())
lyr = MSMap.getLayerByName(SearchLayer)
MSMap.setExtent(CurrentExtent.minx, CurrentExtent.miny,
CurrentExtent.maxx, CurrentExtent.maxy)
If SearchLayer = "Places" Then lyr.data = "..\ExplorOz\Places\" &
PlacesPOIName
Dim s As New System.Text.StringBuilder
result = lyr.queryByRect(MSMap, CurrentExtent)
If result = RESULT_CODE.MS_SUCCESS Then
Dim resCache As resultCacheObj = lyr.getResults
If resCache.numresults > 0 Then
Dim shp As shapeObj
Dim fName As String
lyr.open()
NumResults = resCache.numresults
For i As Integer = 0 To resCache.numresults - 1
shp = lyr.getFeature(resCache.getResult(i).shapeindex,
resCache.getResult(i).tileindex)
For iItem As Integer = 0 To lyr.numitems - 1
fName = lyr.getItem(iItem)
If fName = "ID" Then s.Append(shp.getValue(iItem) & ",")
Next
shp.Dispose()
Next
If s.Length > 1 Then s.Remove(s.Length - 1, 1)
lyr.close()
End If
'If SearchLayer = "Places" Then
' Response.Write(NumResults)
' Response.Write("<br />" & s.ToString)
' Exit Sub
'End If
lyr.Dispose()
MSMap.Dispose()
End Sub
You will see that I dispose every element I create, this has been tried on two
servers (and the production system - dual cpu, 2GB ram) - I do stress the
application with hundreds of users per hour. The exception thrown is as
follows:
Server Error in '/' Application.
---------------------------------------------------------------------------
-----
msLoadMap(): Memory allocation error.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information about
the error and where it originated in the code.
Exception Details: System.ApplicationException: msLoadMap(): Memory
allocation error.
[ApplicationException: msLoadMap(): Memory allocation error. ]
mapObj..ctor(String filename) +54
MapSearch.Query() +52
MapSearch.Page_Load(Object sender, EventArgs e) +284
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061
Any thoughts or help on this would be great, I have invested a heap of time
on this interface and do not want to go back to calling the cgi system as it is
slower - I am using the pre-compiled binaries in the MS4W package as
downloaded two days ago.
David Martin
More information about the MapServer-users
mailing list