Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6143935
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T18:35:05+00:00 2026-05-23T18:35:05+00:00

I have an app that’s built using Appcelerator Titanium (for iOS, latest SDKs of

  • 0

I have an app that’s built using Appcelerator Titanium (for iOS, latest SDKs of Ti and Apple) and a section of it relies heavily on maps. The problem I’m having is that the memory doesn’t seem to be releasing when I close the window containing the MapView. As a result, going back and forth from the menu screen to a map slows down the iPhone until it eventually stops responding altogether (3-5 map loads).

I used Titanium’s Ti.Platform.availableMemory call to see the memory upon entering the window with the map, and after the map is closed. The result is a steady downward trend with each successive entry/exit, along the lines of:

25 (initial load of map.js)
20 (after annotations)
20 (after win.close())
19 (second load of map.js)
18 (annotations)
19 (leave)
18 (enter)
16 (annotations)
15 (leave)

In the simulator, it may go up a little more when the window’s closed, but even it shows a steady downward trend.

Here’s the code for the map, which is in it’s own “map.js” file. I’ve trimmed it down to the functionality code that is used (hence why only the event listener for button_index is here).

button_index.addEventListener('click', function()
{
    Ti.App.xhr.abort();
    if (mapview) {
        mapview.removeAllAnnotations();
        mapview = null;
    }
    if(policeJson){
        policeJson = null;
        fireJson = null;
    }
    Ti.App.police = false;
    Ti.App.types = null;
    win.close(); //This should clean up everything, according to the docs
    Ti.API.info('Memory: ' + Ti.Platform.availableMemory);
});

var mapview;// = Ti.App.mapview;

Titanium.Geolocation.purpose = "Recieve User Location";
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Ti.API.info('Memory: ' + Ti.Platform.availableMemory);

function getMarkers(e){
    var miles = Ti.App.miles;
    Ti.API.info("Getting markers");
    //Google's API radius is in meters, so we need to convert
    var radius = miles * 1610; // 1mi = 1609.344 meters, so we just round up to 1610.
    // http connection setup
    Ti.App.xhr.setTimeout(10000);

    googleLatLng = e.coords.latitude + "," + e.coords.longitude;

    Ti.App.xhr.onload = function()
    {
        var data = Ti.XML.parseString(this.responseText);

        var ref = data.documentElement.getElementsByTagName("reference");
        if(ref != null && Ti.App.xhr.readyState == 4){
            for(var i =0; i < ref.length; i++){
                var marker = new Object();
                marker.lat = data.documentElement.getElementsByTagName("lat").item(i).text;
                marker.lng = data.documentElement.getElementsByTagName("lng").item(i).text;
                marker.name = data.documentElement.getElementsByTagName("name").item(i).text;
                marker.ref = ref.item(i).text;
                addMarker(marker);
                marker = null;
            }
        }
    };
    Ti.App.xhr.open("GET","https://maps.googleapis.com/maps/api/place/search/xml?location=" + googleLatLng + "&radius=" + radius + "&types=" + Ti.App.types + "&sensor=true&key=" + Ti.App.apiKey,false);

    Ti.App.xhr.send();
    Ti.API.info('Memory: ' + Ti.Platform.availableMemory);
}

// find the user's location and mark it on the map
function waitForLocation(e)
{
    var region = null;
    if ( e.error ) {
        region = regionDefault; // User didn't let us get their location
        var alertDialog = Titanium.UI.createAlertDialog({
            title: 'Geolocation',
            message: 'We were unable to center the map over your location.',
            buttonNames: ['OK']
        });
        alertDialog.show();
    } else {
        region = {
            latitude: e.coords.latitude,
            longitude: e.coords.longitude,
            animate:true,
            latitudeDelta:0.05,
            longitudeDelta:0.05
        };
    }
    Ti.App.lat = region.latitude;
    Ti.App.lng = region.longitude;
    mapview.setLocation(region);

    mapview.removeAllAnnotations();
    currentLoc = Titanium.Map.createAnnotation({
        latitude: region.latitude,
        longitude: region.longitude,
        title: e.error ? "Columbus" : "You are here!",
        pincolor: Titanium.Map.ANNOTATION_RED,
        animate:true
    });
    mapview.addAnnotation(currentLoc);
    mapview.selectAnnotation(currentLoc);
    mapview.addEventListener('click', function(e){
        if (e.clicksource == 'rightButton') {
            if (e.annotation.spotUrl != '') {
                alert('Website!');
            }
            else {
                alert('No website available');
            }
        }
    });

    if(Ti.App.police == true) {
        var fire_img = "../../images/iNeighborhood/fire.png";
        var police_img = "../../images/iNeighborhood/police.png";
        serviceMarkers(fire_addr, fire_title, fire_lat_1, fire_long_1,fire_img);
        serviceMarkers(police_addr, police_title, police_lat_1, police_long_1,police_img);
    }

    getMarkers(e);
}


function addMarker(marker){
    var ann = Titanium.Map.createAnnotation({
        animate:true,
        latitude:marker.lat,
        longitude:marker.lng,
        title:marker.name,
        pincolor: Titanium.Map.ANNOTATION_GREEN
    });

    mapview.addAnnotation(ann);
}

// Automatically refresh current location.
/*
 * IN PROGRESS
 */
function getLocation(){
    // create the mapView and center it on Columbus
    if (!mapview) {
        mapview = Titanium.Map.createView({
            mapType: Titanium.Map.STANDARD_TYPE,
            animate: true,
            region: {
                latitude: 39.961176,
                longitude: -82.998794,
                latitudeDelta: 0.1,
                longitudeDelta: 0.1
            },
            regionFit: true,
            userLocation: true,
            visible: true,
            top:29
        });

        //Ti.App.mapview = mapview;

        win.add(mapview);
    }
    refresh();

    //Get the current position and set it to the mapview
    Titanium.Geolocation.getCurrentPosition(waitForLocation);
}
getLocation();

// pretty self explanatory...
function cleanMap(){
    if (mapview) {
        mapview.removeAllAnnotations();
    }
    if(xhr){
        xhr.abort();
    }
}

Ti.App.addEventListener('map:mapIt',function(){
    cleanMap();
    getLocation();
});

Here’s some of the code from the index page that loads the map:

var winMap = Titanium.UI.createWindow({
    url:'map.js',
    tabBarHidden:false
});

btnEducation.addEventListener('click',function(){
    Ti.App.types = Ti.App.schools;
    Ti.UI.currentTab.open(winMap);
    Ti.App.police = false;
});

I made a global HTTPClient and reuse it, like what some of the other Q&A answers (both on SO and on Appcelerator’s site) have suggested, which seems to have helped (not as much memory is drained with each map load), I also tried manually setting the variables (especially the larger ones) to null (which may or may not be effective), but something’s still holding on. I also tried creating the map window inside the event listener for the buttons that open the window, but that didn’t seem to have any effect at all.

I also ran Instruments to see what it could find and it didn’t find anything noteworthy (I even showed it to my coworker, who does mobile development full time and he said there wasn’t anything out of the ordinary that he could see).

I’ve been looking at this code for a few hours now, and it’s not all my code, so it’s entirely possible I’m missing something obvious, but is there a reason in my code why the memory isn’t being released as it should? Is there something else I could do to get more of the memory to release? I’m only developing for iOS right now, so iOS-specific solutions are acceptable.

Edit – I’ve now also tried including the map portion into the file that calls it (using Ti.include('map.js')). I made a quick and dirty setup to see if it would work:

Ti.include('map.js');
var button_index = Ti.UI.createButton({
   text:'Back',
   height:20,
   width:50,
   top:0,
   left:0,
   color:'#000'
});
button_index.addEventListener('click', function()
{
    Ti.App.xhr.abort();
    if (mapview) {
        mapview.removeAllAnnotations();
//        mapview = null;
    }
    if(policeJson){
        policeJson = null;
        fireJson = null;
    }
    Ti.App.police = false;
    Ti.App.types = null;
    Ti.App.title = null;
    mapview.hide();
    Ti.API.info('Memory: ' + Ti.Platform.availableMemory);
});
mapview.add(button_index);
mapview.hide();

btnArts.addEventListener('click',function(){
    Ti.App.types = Ti.App.arts;
//    Ti.UI.currentTab.open(winMap);
mapview.show();
Ti.App.fireEvent('map:mapIt'); //Triggers the chain of events to clear the map and add the necessary annotations to it
    Ti.App.police = false;
    Ti.App.title = 'arts';
});

It seems to work better, but there is still a steady decrease in the amount of available memory as I go in and out of the mapview, and the initial memory load makes it as unusable on the devices as the other method (drops memory down to about 3MB).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T18:35:05+00:00Added an answer on May 23, 2026 at 6:35 pm

    From the docs regarding tabs/tab groups…”A TabGroup Tab instance. Each Tab instance maintains a stack of tab windows. Only one window within in the Tab can be visible at a time. When a window is closed, either by the user or by code, the window is removed from the stack, make the previous window visible.”

    One guess is that the close() when applied to a tab might not act the way you’d assume it would, since it seems to maintain state between the tabs as you cycle between them. Also, maybe there’s something missing in the code example above, but I didn’t actually see where
    “win” was defined as a variable (i’m assuming you have var win = Ti.UI.currentWindow(); somewhere but you might want to double check that it is actually getting closed when that function is called.

    You may also look into creating a single object for your application, and chaining the functions to that object, so as not to pollute the global scope. See: http://wiki.appcelerator.org/display/guides/JavaScript+Best+Practices

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a app that I'm deploying to a development server using Capistrano. I'd
I have an App that will send authenticated emails using System.Net.Mail and System.Net.NetworkCredential my
I have an app that struggles to perform well on iOS 5 running on
I have an app that is saving to a db (using Entity Framework) and
I have an app that's a simple clone of reddit. Using Devise you can
I have an app that uploads files to server using the webclient. I'd like
I have an app that I pack into binary form using PerlApp for distribution.
have an app that finds your GPS location successfully, but I need to be
Have an app that has listings - think classified ads - and each listing
I have an app that needs to open a new window (in the same

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.