[mapguide-trac] #1294: custom output causes memory leak?

MapGuide Open Source trac_mapguide at osgeo.org
Sun Mar 14 22:24:31 EDT 2010


#1294: custom output causes memory leak?
----------------------------------------------+-----------------------------
 Reporter:  ioly                              |         Owner:       
     Type:  defect                            |        Status:  new  
 Priority:  medium                            |     Milestone:       
Component:  Web API                           |       Version:  2.0.2
 Severity:  critical                          |    Resolution:       
 Keywords:  custom output render memory leak  |   External_id:       
----------------------------------------------+-----------------------------
Comment (by ioly):

 I've tried 2.1 but the problem still exists.

 I use the bundled tomcat and the sample package "Sheboygan".

 There are two jsp pages and one core class in my app: open_map.jsp,
 render.jsp, and class "MapService". "open_map.jsp" create a map guide
 session(and put everything in a global cache,  site connection, map,
 session, rendering service and resource service),  "render.jsp" use the
 former created session to generate custom output, and class "MapService"
 wraps the low-level operation.

 When tomcat started up, I first visit the "open_map.jsp" to create a
 session, and then I  visit "render.jsp" in the same browser window to get
 the output image, and then I refresh the page again and again. The output
 image is fine, but the memory use increases very fast.

 '''open_map.jsp:'''
 {{{
 <%@page import="GIS.MapGuide.Data.Map"%>
 <%@page import="GIS.MapGuide.Service.MapSession"%>
 <%@ page import="GIS.MapGuide.Service.MapService"%>
 <%@page contentType="text/plain;charset=gbk"%>
 <%
     MapService service = new MapService();

     Map map =
 service.open("Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition");
     session.setAttribute("map", map);
     out.println(map.toString());
 %>
 }}}



 '''render.jsp:'''
 {{{
 <%!
     double inchToMeter(double inch){
         return inch * .0254d;
     }

     static double _scale = 50000d;

     void _log(Object s){
         System.out.println(s);
     }
 %>
 <%
     try {
         _log("begin: " + System.currentTimeMillis());

          if (_scale < 1000){
             _scale = 50000;

         }else{
             _scale *= 0.9;
         }

         Map map = (Map)session.getAttribute("map");
         MapService service = new MapService();

                 RenderOption option = new RenderOption();
                 option.SessionId = map.getSessionid();
                 option.Scale = _scale;
                 option.CenterX = map.getViewCenter().getX();
                 option.CenterY = map.getViewCenter().getY();
                 option.ImageWidth = 600;
                 option.ImageHeight = 600;

         byte[] buffer = service.render(option);
         _log("size: " + buffer.length);

         response.setHeader("Content-type", "image/png");
         response.getOutputStream().write(buffer, 0, buffer.length);

         _log("end: " + System.currentTimeMillis());

     }catch (Exception e) {
         e.printStackTrace();
     }
 %>
 <%@ page import="GIS.MapGuide.Data.Map" %>
 <%@ page import="GIS.MapGuide.Data.RenderOption" %>
 <%@ page import="GIS.MapGuide.Service.MapService" %>
 }}}


 '''MapService.java:'''
 {{{
 package GIS.MapGuide.Service;

 import GIS.MapGuide.Data.Map;
 import GIS.MapGuide.Data.RenderOption;
 import org.osgeo.mapguide.*;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;

 public class MapService {
     private static String _config_file;

     public static void setConfigFilePath(String path) {
         _config_file = path;
         MapGuideJavaApi.MgInitializeWebTier(_config_file);
     }

     public Map open(String identifier) throws MgException {
         //login
         MgUserInformation user = new MgUserInformation("Administrator",
 "admin");
         MgSite site = new MgSite();
         site.Open(user);

         //create session
         String sessionId = site.CreateSession();

         MgSiteConnection con = new MgSiteConnection();
         con.Open(user);

         //get resource service
         MgResourceService resource_service =
 (MgResourceService)con.CreateService(MgServiceType.ResourceService);


         MgMap mm = new MgMap(con);
         MgResourceIdentifier id = new MgResourceIdentifier(identifier);
         _log(id.ToString());
         _log(id.GetName());
         mm.Create(resource_service, id, id.GetName());

         String sid = String.format("Session:%s//%s.%s", sessionId,
 mm.GetName(), MgResourceType.Map);
         _log(sid);
         mm.Save(resource_service, new MgResourceIdentifier(sid));
         _log(mm.GetResourceId().ToString());
         _log(mm.GetMapDefinition().ToString());

         //output
         MapSession session = new MapSession();
         MapSessionManager.put(mm.GetSessionId(), session);

         session.setMap(mm);
 session.setRenderingService((MgRenderingService)con.CreateService(MgServiceType.RenderingService));
         session.setResourceService(resource_service);
         session.setSessionId(sessionId);
         session.setSite(site);
         session.setSiteConnection(con);
         session.setUser(user);

         Map map = new Map();
         map.setMap(mm);
         _log(map);

         return map;
     }

     void _log(Object s){
         System.out.println(s);
     }

     double _inch_to_meter(double inch){
         return inch * .0254d;
     }

     public byte[] render(RenderOption option) throws MgException,
 IOException {
         MapSession session = MapSessionManager.get(option.SessionId);
         MgMap map = session.getMap();
         String srsWkt = map.GetMapSRS();
         MgCoordinateSystemFactory coordinateSystemFactory = new
 MgCoordinateSystemFactory();
         MgCoordinateSystem srs = coordinateSystemFactory.Create(srsWkt);

         double displayInInches = option.ImageHeight * 1d  /
 map.GetDisplayDpi();
         double displayInMeters = _inch_to_meter(displayInInches);
         double mapHeightInMeters = displayInMeters * option.Scale;
         double mapHeightInMapUnits =
 srs.ConvertMetersToCoordinateSystemUnits(mapHeightInMeters);
         double envelopeOffsetY = mapHeightInMapUnits / 2;
         double envelopeOffsetX = option.ImageWidth * 1d /
 option.ImageHeight * envelopeOffsetY;
         MgEnvelope envelope = new MgEnvelope(
                 option.CenterX - envelopeOffsetX,
                 option.CenterY - envelopeOffsetY,
                 option.CenterX + envelopeOffsetX,
                 option.CenterY + envelopeOffsetY
         );

         byte[] tmp = new byte[1024 * 1024];

         MgSelection selection = new MgSelection(map);
         MgByteReader byteReader = session.getRenderingService().RenderMap(
                 map,
                 selection,
                 envelope,
                 option.ImageWidth,
                 option.ImageHeight,
                 new MgColor(option.R, option.G, option.B),
                 "PNG"
         );

         ByteArrayOutputStream buffer = new ByteArrayOutputStream();

         while (true) {
             int len = byteReader.Read(tmp, tmp.length);
             log(len);
             if (len <= 0){
                 break;
             }
             if (len > 0) {
                 buffer.write(tmp, 0, len);

             } else {
                 break;
             }
         }

         byteReader.delete();
         tmp = buffer.toByteArray();
         buffer.close();
         return tmp;
     }

     void log(Object s){
         System.out.println("MapService: " + s);
     }
 }
 }}}

-- 
Ticket URL: <http://trac.osgeo.org/mapguide/ticket/1294#comment:3>
MapGuide Open Source <http://mapguide.osgeo.org/>
MapGuide Open Source Internals


More information about the mapguide-trac mailing list