Mobile: Does removing Memory Leaks on iOS also remove leaks on Android?

Hi all,

I've read a lot about Memory Leaks in Wiki Managing Memory Leaks and Forum posts.

I removed nearly all memory leaks in my app. At least on iOS. It's very easy to monitor them on iOS. But on Android, the heap / memory usage is always growing and nothing is released (and least it seems so). I'm not sure whether it's caused by a few Titanium issues ( eg TableViewRow Leak ) or whether it's my code.

Thus my question. If I removed all my memory leaks on iOS. Does this also remove my memory leaks on Android? Granted that the code is the same.

I'm not sure whether the Garbage Collector in JavaScriptCore and v8 works similar.

Thx + Greetings

— asked 4 years ago by Jicks Steen
  • There is no tool in android to find this like in iOS. You can only come to know this when it will force close because of memory leaks.

    — commented 4 years ago by Yogin Bhungalia
  • Actually, I get a force close after some actions at the moment. I'll wait now till the memory issues are fixed.

    — commented 4 years ago by Jicks Steen
  • Latest Titanium Build 1.9.0 fixes my memory leaks. Hope the fix will be merged into Titanium 1.8.2 branch. Thx for your repsonse.

    — commented 4 years ago by Jicks Steen

5 Answers

  • Hi Jicks

    Well in android the garbage collection is maintain automatically and we dont have to code anything separately for that i guess that the default nature of java. Well but i am not sure with the v8 functionality. But memory leaks in android is not an issue unless your app is using a lot of memory where its not even needed.



  • Hi Jicks.

    When looking for memory leaks on Android, people are usually over-paranoid. The thing is that memory management and GC (garbage collection) is very sensitive action in terms of performance and Android handles this very randomly (GC occurs when there are enough free resources in system). Garbage collector will clean memory when it thinks that it should and it releases it as much as it thinks it should.

    So, because of that, people usually are paranoid because they released an object (variable = null;) but memory has not been released. Nulling a variable is just like you said to GC - I don't need this memory anymore (and most people think they said - free this memory at once! :D ). That does not guarantee anything in terms of free memory. To see do you have memory leaks, run your app for some time and see how free memory levels behave. If free memory is constant over time, you can say that you don't have memory leaks.

  • I guys I am also having a similar issue. I have nulled all variables and removed everything in my iOS version, so in theory that should also clean up memory in my Android version. None of the above post really answered the original question. In my Android version the memory only gets cleaned up a little bit but over time continues to grow and crash the app, this does not happen in my iOS version. Does anyone else have similar behavior?? I am using single context with 1 window and views that get created and removed as needed. Which version of 1.9 may fix this issue? Thanks for any input.

    — answered 4 years ago by sean sean
    • Hey I'm struggling with the same issue on Android. I've tried all the known workarounds for tidying up memory in Appcelerator Views (including this one

      Using the DDMS tool with the Android Emulator I see apps memory increase rapidly as viewed in the 'SysInfo' tab. Interestingly that actual Java VM heap memory is not the problem as the stats from the 'VM Heap' tab in DDMS show no real growth in the heap usage.

      What I think is happening is that the native memory allocated to the view by Titanium is not being freed until the Java VM heap is garbage collected. It's only a theory but I did see an article stating that TI's proxy objects don't release all their native memory until the objects are GC'ed. This would make perfect sense as if I use the DDMS tool to force a garbage collect the memory gets freed.

      Unfortunately as yet I can't figure out an easy solution to this problem. There doesn't seem to be a way to force garbage collection from the Javascript code (and forcing a GC is not a very nice way to fix it anyway).

      — commented 4 years ago by Andy Potter
    • Andy,

      My issue is that they (Appcelerator) say that if you remove and null objects they will be GCd by the Android OS and we should have to force any garbage collection. I wrote my app first in iOS and used Instruments to check for all memory leaks. I then ported the same code to Android (with some minor mods to properties to adjust for differences) and its leaking memory like crazy. It would be nice if Appcelerator provided some sort of sample program that could demonstrate memory being cleaned up in Android just see the objects actually getting cleared up. That way you could run that sample with every new release and verify that nothing has been broken.

      — commented 4 years ago by sean sean
    • Setting a variable to 'null' does NOT force the object to be immediately garbage collected. It just tells the VM that you no longer need the object in this scope, if there are other references elsewhere to the object then it will NOT be garbage collected. And even if you 'null' the only reference to the object you can't be sure when the garbage collector will next run. But I think the garbage collection is not the issue, it's the fact that the Ti Proxy objects have native memory allocations outside the VM which are not freed until the Proxy objects are GC'ed.

      — commented 4 years ago by Andy Potter
    • UPDATE - I've narrowed the source of my issue down to the 'backgroundImage' property. It seems if you use this on a view (any kind of view, plain, button, imageview, etc) and then you remove the view and null the reference you get a nice big leak in native memory. This leak does get freed when the GC runs, but because it leaks so much (nearly 1MB per view in my case), you can easily get the device to run out of memory and force close your app before the GC kicks in (NB: You don't always get killed, sometimes you just start getting OutOfMemory exceptions in the log).

      Changing my app to use 'ImageView' instead of a plain 'View' AND using the 'image' property instead of the 'backgroundImage' property fixes the leak. However this doesn't entirely help me because I need my images stretched to fit the screen, but the ImageView always maintains aspect ratio if you specify the image via the 'image' property.

      So I'm still a bit stuck, the investigation continues…

      — commented 4 years ago by Andy Potter
    • hmmm, that might help my issue. If you have global variables and then null them out later in the program, will they ever get cleaned up? Im guessing not from your previous post.

      — commented 4 years ago by sean sean
  • NB: SDK 1.7.5 on Android, haven't tried any other SDK versions and don't know if this affects iOS - This doesn't necessarily answer all memory leaks/out of memory scenario's but certainly this one caused me a big headache and the workaround is NOT obvious at all. See my comments on 'sean sean' post above for the background but basically if you use the 'backgroundImage' property of any type of view and you then 'remove' that view from it's parent you will get a lot of native memory left unfreed until the next GC. This can result in you're app getting OutOfMemory errors in the log or even a 'Force Close'.

    Long story short to workaround this issue you can do one of two things:

    1 - If you don't need your image stretched to fit the view then use an 'ImageView' and set the 'image' property instead of the 'backgroundImage' property. Then when you want to remove your view and free the memory be sure to remove it from it's parent view, set the 'image' property to empty string and then 'null' your reference variable. e.g.

    imgView.image = '';
    imgView = null;

    2 - If you do need your image stretched to fit then because 'ImageView' maintains aspect ratio you have to use a bit of a hack. Basically you can use a 'Button' view but make it disabled (i.e. enabled = false), set 'style = 0', and 'width' and 'height' to 100% otherwise it won't expand to fill the parent. Then use the 'backgroundDisabledImage' property to set your desired image. Then you want to remove your view and free the memory it's the same as above but you set the 'backgroundDisabledImage' to an empty string, e.g.

    button.backgroundDisabledImage = '';
    button = null;

    NB: For tracking this problem down the DDMS tools was absolutely essential. Strongly recommend you know how to use this tool effectively for investigating memory leaks.

    — answered 4 years ago by Andy Potter
    • Hi Andy,

      There are still plenty of memory issues I think. I am using the latest studio version and a very recent build of SDK version 1.9.0. I created a very simple test case to show the memory issues.

      1. Create a new project
      2. Modify app.js with the following.
        var rootWin = Titanium.UI.createWindow(
        //backgroundImage: '/images/background2.jpg',
        backgroundColor: 'white',

      var createViews = Ti.UI.createButton({
      title: "Create Views",
      top: 10,

      //alert('views created');


      var releaseView = Ti.UI.createButton({
      title: "Release Views"

      mainViews = null;
      //alert('views Cleared');


      Then create another js file called selfCalling.js with the following code:

      (function mainViews()
      var views =[];
      var view = null;

      for (var i=0; i < 1000; i++) {
          view = Titanium.UI.createView(
              //backgroundImage: '/images/background2.jpg',
              //backgroundColor: 'blue',
      views =[];
      views = null;  
      view = null;



      If you run this with the DDMS tool you will see that the memory never gets cleaned up or garbage collected even though right after I create the array with views I null the variable out.

      Do you think this is a valid test case to prove memory leaks?


      — commented 4 years ago by sean sean
    • I have just tested the above code on a mac with the latest Studio version and sdk 1.9.0.(1.9.0.v20120131141634). It works as expected, it creates the objects and properly cleans up the memory automatically. (Proved it using instruments) Does anyone know why this would only work on iOS? On Android the memory just keeps climbing until it crashes.

      This is about as "hello world" as it gets!!!

      Any ideas would be greatly appreciated.

      — commented 4 years ago by sean sean