My app is very slow, than ı searched web and find out there are memeory leaks on my app. But the problem is ı have tons of codes and too many activities. There are tons of refenrences and leaks. Its gonna be really hard work if ı do this way. Than I tougth if I transfer all codes to a services (as ı understand the services is not leaking memory) this would be easier for me. I wnant to ask that, if you had this statuation, than how would you try to solve it? I learned about memory managment 4 days ago and 10 hours of day learned about it. But ı dont want to go wrong direction again. And my app live on market and users still waiting for a update. I need to be fast and affactive more than I can be. How would you salve this leaks on fastest way ? Is servis realy a option ?Thanks..
I decided to clear all leaks and make a better codding. This is absolute way. By the way, for more performance, when a activity is hidden clear all data that took. and clear all images. if activity is active again reload all contents again.
also: create a clas and make a static instance of aplication context. then call this where you wrigth .getaplicationcontext(). this thecnic called by weak reference. by this your activities will be garbace collected.
and use this.isfinishing() method at onpost() method of every asyctask.
you can use onstart and onstop calls for this. my apps ram usage was 250 mb and now 70mb.
Related
Alright so I'm going to try to explain one problem at a time so you can understand the issues I'm having and hopefully someone will be able to tell me hoe to fix it. So my app runs perfectly but my users have been complaining of high ram usage and on average it runs any where from 120mb to 200mb IDLE which I agree isn't right so I went ahead and remembered a trick I used in a previous project and that was this line of code android:hardwareAccelerated="false". This removes about 10mb of ram per activity but I'm still sitting at about 90mb of usage so i went and looked a little harder and found this android:process=":ProcessName"> which takes my app from using 100mb to a mere 8mb of ram. But I'm facing a problem while doing this and that is the fact that I have a LocalBroadcastManager in a service activity that sends data to my MainActivity and when these two have different processes they don't communicate with each other, and if I combine them into the same process the usage spikes yet again. So I'm kinda stuck what to do at this point and I refuse to use the Android Memory debugger because it doesn't tell me jack crap about what my code is doing wrong. Quite literally I have 5 text views and an imageview inside of my MainActivity so I know its not that intensive by any means! If anyone needs code please let me know but I figured someone really didn't need to look at the code to answer this!
You wrote:
But I'm facing a problem while doing this and that is the fact that I have a LocalBroadcastManager in a service activity that sends data to my MainActivity and when these two have different processes they don't communicate with each other, and if I combine them into the same process the usage spikes yet again.
You can keep your Service in a separate process and bind to it from your app's first process, via IPC, inter-process communication.
See:
http://developer.android.com/guide/components/bound-services.html
There are different ways to do IPC. The Messenger option might be a good starting point for you:
http://developer.android.com/guide/components/bound-services.html#Messenger
From the documentation:
If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.
In my app, I use a static variable to hold the current user id. There is a bug that is very hard to reproduce of this user id simply disappearing. While it could be related to a bug in how this variable is set during application loading (I still wasn't able to reliably reproduce this situation in a controlled environment, so I'm not really sure exactly what happens), I'm starting to think this is related to how memory gets reclaimed from static variables (something I didn't consider before).
So, when can my static variable simply disappear?
As far as I understand, static memory can get reclaimed if the OS reports low memory - can it happen while the app is in the foreground? Or only background?
Are there any possible ways static memory is getting reclaimed without a low memory condition? I think sometimes the variable disappears without the app even going to the background and I'm not sure any low memory events occur (AFAIK low memory refers to the whole OS, not the app's memory)
What is a good way to simulate static variables getting reclaimed by the OS to see how the application behaves and subsequently fix the bugs?
Anything adding more clarity to my understanding will be appreciated.
Thank you.
This is question super, super old, but I was writing a blog post and mentioned seeing this. I have no idea if you're still working on this app (doubtful), or if you're still seeing this issue (also doubtful). My guess is you set these statics in the Activity that your app launches with. Of course, if your app gets shut down, then restarted, you won't go through that activity.
Lazy loading statics, or initializing them in a custom Application object generally takes care of this.
I've done a fair amount of research on the "statics removed in low memory" idea, and the basic answer is it doesn't happen. Ever.
I suggest you are not using static variable to hold the current user ID as the static variable is not one of the best way to store your data (I assume userID as a data which will remain on every session of your app, except when the user is logout).
The simplest way is to go with Shared Preferences. Look at the Android Data Storage to read the best (practice) way to store your data in Android.
From your need, I guest you should go on with SharedPreferences. No more problem and you don't even need to simulate any variables reclaimed by the OS.
I've been digging the web in quest of finding nice, androidish solution for this concrete problem, but havent found one, so here I am, posting my first question on StackOverflow.
To elaborate on my problem, I have a full-fledged aidl service, to which some other processes bind. My service will allocate some resources for each of process connecting to it, and I want to make this statement bold, the resource allocation is made for process, I make some kind of a session tracking, where getCallingPid() and getCallingUid() play a role of session identifiers.
So the problem here is that Android will never tell us if an application which was bound to us went away for some reason, so the system resources allocated for that destroyed process would be wasted away by being held by our service.
One solution that I found somewhat feasible is just to poll ActivityManager.getRunningAppProcesses and calculate set difference between current and previous snapshots, but this method looks really dirty.
Could anyone suggest some better method to do this? I'd be really grateful!
Thanks,
Giorgi
As far as I'm aware, Android won't tell you when processes are killed.
I suspect the only method is to get a list of running applications every x seconds or minutes, and keep track of the applications that way. I think this is what you already suggested in the question as well.
It's not pretty, but it's likely one of the only ways to do it.
I've an application that has some foreground activities and also a service that updates some widgets.
The problem is that, as the process remains for the service, the memory from the other activities ,if they are opened, is never reclaimed.
Looking at that response from Roman Guy it seems that can be normal. But it is? For how much time android keeps the resources of not used activities? They can live for hours?
How can I know easily if the activities are leaked or are simple not reclaimed? I've tried with a program from AndroidMarket (FreeMemoryRecover) and it's cleared but I suspect that it kills the process and then restart the service...
Any help or suggestion will be heavily appreciated.
Note 1: I've investigated with a HeapDump + Eclipse MAT and I don't see strange references holding my activities
Note 2: I've already asked some questions about this problem:
Post 1
Post 2
The ability for Android to have multiple Activities, in different states, is a design principle as it allows users to quickly switch between activities without consciously having to shutdown whatever they were doing before. They can then quickly return to a previous activity.
If Android needs to pause an Activity, and quickly unpause it, it's going to need to keep the Activity's resources available to it.
If the memory is part of a terminated Activity, then it's leaked (very unlikely as the Linux kernel will reclaim all memory that was used when the process terminates), else it's either being actively used or is potentially about to be used.
What is that concerns you about this memory?
I would try the following :
Launch your app play with it to be sure it is fully loaded and use as much memory as it can.
Then hit the home button and launch the navigator, open techcrunch.com, lemonde.fr, youtube.com, dailymotion.com, launch a video from youtube, open up and play angry bird and last but not least open up a pdf document.
After that Android will have needed the memory back quite for sure. If your app is still there, you might have a problem, if its not, then everything went smoothly.
By the way, good on you to put so much concern in being a good citizen in AndroidLand !!
See my comment below your question.
See Romain Guy's post about Android memory leaks.
Specifically, look at the comment on the solution in the Launcher app. (look at unbindDrawables code here)
Use Context.getApplicationContext() whenever possible instead of your activity's context.
I have a couple quick questions. They all deal with 1 general topic, and one strategy may take care of everything, so I hope that its ok I put them under the same topic.
I have had trouble finding solid info on garbage collection, so would appreciate any help, I think perhaps I don't fully understand what I am reading in the MAT. Even if you can answer 1 question I would be super happy
What is the best strategy for finding memory leaks in Android? As best I can tell it is to get the Eclipse MAT, picking an object that isn't getting garbage collected (using the dominator tree, or whatever is easiest for you to find it with), and displaying the shortest merged paths to the gc of that object and find the furthest incoming reference to that object that you can control and killing that reference on destroy. This works to kill the references, but sometimes the object still doesn't get garbage collected
Is it good practice to null all of your handlers/runnables/threads/listeners on destroy? Some of these seem to stick around indefinitely if I don't, and sometimes even if I do.
What is the best way to ensure that a thread gets garbage collected, even if the reference is nulled (they seem to stick around sometimes)?
Why oh why can't I get the google analytics tracker to get garbage collected, even though it has no reference from my application at all. It seems to maintain a reference to my activity, so I think that might have something to do with my GC problems.
Thanks you!
The best strategy is to fully understand the implications of what you are doing from the beginning, and thus avoid memory leaks in the first place. See, for example, handling memory leaks in Java. Otherwise, that seems like a fine approach along with code inspection. Are you forcing a GC to prove that the object still isn't collected?
In general, no. This article has a good explanation as to why.
Don't hold any references to it? Follow standard coding practices as described above.
Don't know. But wouldn't you be using it throughout your application, so it doesn't really matter? Eventually Android will kill your whole process and reclaim the memory anyways.