Hi !
I'm developing me first "real" (some minor projects before) app for android. Right now i'm trying to optimize the memory usage, regarding to this I have a question. I hope someone can help me.
I've implemented a foreground service, which also updates some UI-elements via a static reference of the MainActivity.
My question is, what happens if the UI is not visible (i.e. MainActivity is destroyed) ? Are these calls ignored ? Are they using memory ?
Thanks in advance!
You shouldn't keep reference objects with short lifecycle from an object with long lifecycle, unless you carefully manage these references.
To answer your question: UI-elements will be kept in memory till ClassLoader will be destroyed or the references will be nullified.
LinuxForce said:
Hi !
I'm developing me first "real" (some minor projects before) app for android. Right now i'm trying to optimize the memory usage, regarding to this I have a question. I hope someone can help me.
I've implemented a foreground service, which also updates some UI-elements via a static reference of the MainActivity.
My question is, what happens if the UI is not visible (i.e. MainActivity is destroyed) ? Are these calls ignored ? Are they using memory ?
Thanks in advance!
Click to expand...
Click to collapse
Once the activity is destroyed there should be no more running resources, ie. memory usage. If you want to stop other UI-elements such as lingering toasts or dialogs, you can overwrite the onDestroy method to do so.
bbish937 said:
Once the activity is destroyed there should be no more running resources, ie. memory usage.
Click to expand...
Click to collapse
What if class has static reference to one of Views, will it be nullified by itself once the Activity destroyed or it will be kept in memory?
Related
My device normally is working very fast as I had applied all the performance tweaks I could find, and had relocated all IE and Opera working files away from the device, and had relocated all temporary, non-volative files out of the device memory too.
Then today I decided to again try out WisbarAdvance 2 (being so attracted by the beautiful themes).
When I could not get it to work (missing task bar, missing task bar icons, missing close button, misisng window start icon, etc) I decided to uninstall it, and when I did that all hell broke lose. The entire unit frozed, and 5 to 6 resets could not bring it to health. It continued to show the device to be critically short of memory when nothing is running. It kicked my TenGo input method off the choice as default input. The today screen itself takes ages to come on and render.
I think it was due to compaction thread kicking in again. I hope microsoft mobile team is looking at this, and would rewrite the compaction thread algorithm. Anyway, just a thought, why should microsoft be worried about wear leveling when the memory card is so cheap? Just use it for a year, and throw it out, but save us the problem of compaction thread! I for once, would not be willing to pay the price of continuous performance freeze caused by compaction thread just because we try to prolong the life of nand ROM card. Another thought, why can't microsoft make compaction thread a job that is scheduled by the user? In that way, I can let it run starting one midnight and stopping 6 am, or whatever time I specify. If we did not let defragmentation program kick in in the least expected moment, why should compaction thread activity be different?
The present compaction thread design is clearly faulty!
Someone suggested that compaction thread affects only devices upgraded from the oldder OS, but this is apparently not true. It is still applicable to devices designed to run WM5. Looks like the algorithm had not changed even after so much problems have been expereinced by WM5 users. I hope WM6 address the wear-levelling problem differently.
I'm thinking whether or not it is a good idea to use the microdrive rather than SD card for storing data. The file system would not do compaction thread on microdrive right? So, if we store our data in there, all the data write would not cause any freezing up like it would with NAND and NOR ROM memory.
I've decided to relocate all my browser cache/history/cookies, data, application\volatle files all to the microdrive instead of Storage Card. Hopefully this would keep compaction thread to the absolute minimum.
So far so good. Have not got any compaction thread kicking in yet.
Will monitor it closely for a few weeks to see if this would solve the problem of erratic sluggishness and freezing up once and for all.
Hey guys. I've been looking around all over for info on the problem with my app. Nothing I found was a concrete answer. here's the problem. I made an app that works really well except it force closes when I hit the back button to finish activity and then start another of the same activity as before. It force closes once in a while when I do this, throwing a log cat error that says out of memory, pointing to where I fill my bitmap cache. There's two reasons im thinking it would be doing this. 1) My bitmap factory is having a problem or 2) I have the context of my activity stored as a variable so I can close activity and that is too much memory. I'm using a panel, which also may add to the problem. Also, another phone can't even start the activity the first time. Any help would be greatly appreciated. This is only problem on app and this fix will make it market ready.
Sent from my SCH-I500 using XDA App
Did you try to explicitly clean up the bitmap references? you should call Recycle() on every bitmap in your activity's onDestroy or wherever you do your cleaning. Another issue I had was with the Bitmap.CreateScaledBitmap method - it leaks, apparently. I made a small static method that uses a transform matrix and then calls Bitmap.CreateBitmap (the overload that takes a matrix, obviously). That change alone solved half my memory issues.
The thing about not loading at all on another phone might be a heap issue. My game loaded just great on my customized SGS, but on the emulator with 24mb of heap it crashed. The reason was that I pre-load all the sprites at the beginning, and apparently 24mb isn't that much
Solution was downscaling and lowering resolution and color depth for the sprites, not much possibilities here - too many bitmaps take too much memory...
I'm guessing the phone you tested likely has a smaller heap than the phone that doesn't make your app crash.
Of course all of the above is mostly guess work, but that's what I can supply right now
i have the problem fc too, but after i upgraded to 2.2. the seem the problem fixed automatically.
Thanks so much! I made it recycle my bitmaps, along with a few minor changes, and it worked great! Thanks for your help!
Sent from my SCH-I500 using XDA App
Hi everyone
I have an irritating dilemma. Whenever the screen goes to sleep/locks, SOMETHING happens and then it crashes when you turn it on again.
let me clarify a bit.
My app is an opengl game. Textures are loaded on the game(logic) thread. the game thread is started by the main thread in the onCreate method.
However,
when the screen wakes up from sleep or 'unlocks' the main threads onCreate gets called again, and therefore textures are loaded again and this make the app run out of memory and crash.
and this ONLY happens when the screen locks, switching between applications works just fine.
----
my question is this:
what happens when the screen goes to sleep or locks? Why does onCreate get called multiple times, and why the hell is there like no information about this specific thing in the Android docs?
EDIT:
also, what happens to threads when the screen is off. Are they terminated or frozen or something?
THANKS!
I would assume your activity is being destroyed/torn down, threads continue to run but become eligible for GC AFAIK.
You should really plan for this in your life-cycle. Do cleanup in onPause, onStop and onDestroy. And check to see if threads/ textures exist in onCreate() onResume() and onStart()
This is actually a generally good habit to be in when writing methods. If you design them in such a way that if they get called multiple times your app will react correctly anyways.
hth
alostpacket said:
I would assume your activity is being destroyed/torn down, threads continue to run but become eligible for GC AFAIK.
You should really plan for this in your life-cycle. Do cleanup in onPause, onStop and onDestroy. And check to see if threads/ textures exist in onCreate() onResume() and onStart()
This is actually a generally good habit to be in when writing methods. If you design them in such a way that if they get called multiple times your app will react correctly anyways.
hth
Click to expand...
Click to collapse
definitely is a good practice to assume nothing and always check for pre-existing textures, values, threads and to either decide to destroy and recreate them or to use the pre-existing values. its a good way to minimize memory leakage and values without pointers, though the vm does a good job of cleanup.
I noticed certain background processes like 'Email' and 'Gallery' kept coming back.
Even after I killed them with 'Advanced Task Killer', they kept popping back up and I want to know how to stop them? I don't want them to run automatically unless I need them.
Why is 'Gallery' kept popping up? I haven't checked any pictures lately.
Good question bro. This should be put to Google's Android forum.
Sent from my GT-I9100 using XDA Premium App
MrRoberts69 said:
I noticed certain background processes like 'Email' and 'Gallery' kept coming back.
Even after I killed them with 'Advanced Task Killer', they kept popping back up and I want to know how to stop them? I don't want them to run automatically unless I need them.
Why is 'Gallery' kept popping up? I haven't checked any pictures lately.
Click to expand...
Click to collapse
Out of interest, why are you bothered about it?
MrRoberts69 said:
I noticed certain background processes like 'Email' and 'Gallery' kept coming back.
Even after I killed them with 'Advanced Task Killer', they kept popping back up and I want to know how to stop them? I don't want them to run automatically unless I need them.
Why is 'Gallery' kept popping up? I haven't checked any pictures lately.
Click to expand...
Click to collapse
Please spend some time to read up on how linux works, specifically how memory is used, and then you will understand how Android works and why these applications keep "coming back".
I cringe everytime I read people talking about taskkiller applications.
kitch9 said:
Out of interest, why are you bothered about it?
Click to expand...
Click to collapse
I like to know how things tick and there is a REASON why the 'Gallery' kept popping back up.
MrRoberts69 said:
I like to know how things tick and there is a REASON why the 'Gallery' kept popping back up.
Click to expand...
Click to collapse
Because this is how android OS works. It loads processes for faster use when needed. There is nothing you can do to stop it, its based on android and its process management method, etc. These apps should be frozen in an idle state using zero resources. Use system panel to confirm gallery is not using any CPU.
They should make the system clever by having it learn what each person uses/doesn't use and only load the processes accordingly . I just find it irritating that it loads stuff that I am never going to use... I don't care that it doesn't use resouces, I just find untidy
I agree, i dont like things to start without me using them first neither! This is just stupid. Also some things should never been shown to users in my opinion. If something is in the kernel and not for me to mess with it should be hidden.
ps. as a user i dont want to spend reading tons of pages on how the OS works in detail, it should be easy to use and dont make the user confused. this is one aspect i hope Android improves in the future.
vampyren said:
I agree, i dont like things to start without me using them first neither! This is just stupid. Also some things should never been shown to users in my opinion. If something is in the kernel and not for me to mess with it should be hidden.
ps. as a user i dont want to spend reading tons of pages on how the OS works in detail, it should be easy to use and dont make the user confused. this is one aspect i hope Android improves in the future.
Click to expand...
Click to collapse
Buy an iphone
Sent from my GT-I9100 using XDA App
First of all starting some processes also start others in anticipation of their use. What is happening is that apps you are using are calling for those to start for quicker launch and there are dependencies that are not immediately obvious that will sometimes start a seemingly unrelated process. Memory management on android is very good and typically with task killers you often work against the built in memory management. I'm going to do a cut an paste here with a few basics....
By default, every application runs in its own Linux process. Android starts the process when any of the application's code needs to be executed, and shuts down the process when it's no longer needed and system resources are required by other applications.
A content provider is active only while it's responding to a request from a ContentResolver. And a broadcast receiver is active only while it's responding to a broadcast message. So there's no need to explicitly shut down these components.
Activities, on the other hand, provide the user interface. They're in a long-running conversation with the user and may remain active, even when idle, as long as the conversation continues. Similarly, services may also remain running for a long time. So Android has methods to shut down activities and services in an orderly way:
An activity can be shut down by calling its finish() method. One activity can shut down another activity (one it started with startActivityForResult()) by calling finishActivity().
A service can be stopped by calling its stopSelf() method, or by calling Context.stopService().
Components might also be shut down by the system when they are no longer being used or when Android must reclaim memory for more active components.
If the user leaves a task for a long time, the system clears the task of all activities except the root activity. When the user returns to the task again, it's as the user left it, except that only the initial activity is present. The idea is that, after a time, users will likely have abandoned what they were doing before and are returning to the task to begin something new.
An activity has essentially three states:
It is active or running when it is in the foreground of the screen (at the top of the activity stack for the current task). This is the activity that is the focus for the user's actions.
It is paused if it has lost focus but is still visible to the user. That is, another activity lies on top of it and that activity either is transparent or doesn't cover the full screen, so some of the paused activity can show through. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.
It is stopped if it is completely obscured by another activity. It still retains all state and member information. However, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.
If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.
The foreground lifetime of an activity happens between a call to onResume() until a corresponding call to onPause(). During this time, the activity is in front of all other activities on screen and is interacting with the user. An activity can frequently transition between the resumed and paused states - for example, onPause() is called when the device goes to sleep or when a new activity is started, onResume() is called when an activity result or a new intent is delivered. Therefore, the code in these two methods should be fairly lightweight.
A few conclusions.....
Android is hard coded to automatically kill a task when more memory is needed.
Android is hard coded to automatically kill a task when it's done doing what it needs to do.
Android is hard coded to automatically kill a task when you haven't returned to it in a long time.
Most services (while possibly running in the background) use very little memory when not actively doing something.
A content provider is only doing something when there is a notification for it to give. Otherwise it uses very little memory.
Killing a process when it isn't ready only causes it to have to reload itself and start from scratch when it's needed again.
Because a task is likely running in the background for a reason, killing it will only cause it to re-spawn as soon as the activity that was using it looks for it again. And it will just have to start over again.
Killing certain processes can have undesirable side effects. Not receiving text messages, alarms not going off, and force closes just to name a few.
The only true way to prevent something from running at all on your phone would be to uninstall the .apk.
Most applications will exit themselves if you get out of it by hitting "back" until it closes rather than hitting the "home" button. But even with hitting home, Android will eventually kill it once it's been in the background for a while.
krabman, thanks mate now your post really helped me a lot to understand these processes
Thought I would record my troubles with a game render loop and a logic engine given a particular bug has swallowed up about a week of my time. I am posting it incase anyone else happens to have the same problem/symptomns.
It originated when I wrote the LogicEngine which has an ArrayList of GameObjects and iterates through them deleting them as nessesary depending on the results of thier processStep.
The render thread would occasionally crash when something was deleted from the array while the list was being drawn but this happened quite rarely. No problem I thought, I'll just catch the out of bounds exception and it will get displayed on the next frame however many milliseconds later.
This all went well for 3 months of coding till I got to programming terrain where about 300 blocks were all displayed gradually scrolling down the screen. The blocks would flash intermittently but in sections not all at once.
At first I thought it was too many blocks for the LogicEngines collision detection so I doubled the size of the blocks. Then I thought it might be overhead allocating memory for the blocks and preloaded them in the constructor. Eventually in despair I disabled the deletion of blocks once they went offscreen and noticed the flashing stopped. This was the point I realised what was happening: The LogicEngine would delete a row of blocks because they went offscreen and the Renderer would be half way through drawing and instead of crashing it would just skip x blocks wherever it was in the for loop at the time that the LogicEngine removed them.
Wow I feel stupid, especially because of the lazy Exception catching solution I originally implemented which masked the problem for so long.
Code:
GameRender.java
//draw obstacles
theLogicEngine.objectsObstaclesLock.writeLock().lock();
for(int i=0 ; i<theLogicEngine.objectsObstacles.size();i++)
{
drawObject(theLogicEngine.objectsObstacles.get(i));
}
theLogicEngine.objectsObstaclesLock.writeLock().unlock();
LogicEngine.java
for(int i=0;i<objectsObstacles.size();i++)
if(objectsObstacles.get(i).processStep(this)) //we are to delete this object
{
objectsObstaclesLock.writeLock().lock();
//remove self if necessary
//move object returned true so delete object
GameObject toDelete = objectsObstacles.get(i);
objectsObstacles.remove(i);
toDelete.dispose();
i--;
objectsObstaclesLock.writeLock().unlock();
}
TLDR: If you have an ArrayList that can be edited by one thread, make sure you lock it rather than just catching the ArrayOutOfBoundsException
Glad you figured it out
I am still impressed that you can write Android games using these techniques. Is your game low-res or is Dalvik that powerful?
I mean, you are using Java, which is one thing, but then you use ArrayList and you delete objects as you go. I take this to mean that you do not recycle them in a pool.
Am I correct?
cyansmoker said:
Glad you figured it out
I am still impressed that you can write Android games using these techniques. Is your game low-res or is Dalvik that powerful?
I mean, you are using Java, which is one thing, but then you use ArrayList and you delete objects as you go. I take this to mean that you do not recycle them in a pool.
Am I correct?
Click to expand...
Click to collapse
ArrayList is self managing.
All of Java's garbage collection is done automatically. As a Java dev u can call System.gc but this only suggest the system attempt gc.
Dalvik is pretty good, but anything extensive I would go native...
Sent from my Galaxy Nexus using Tapatalk
jug6ernaut said:
ArrayList is self managing.
Click to expand...
Click to collapse
Right. But then there is the memory consumption issue. That's why I typically do things as described in this blog entry.
jug6ernaut said:
All of Java's garbage collection is done automatically. As a Java dev u can call System.gc but this only suggest the system attempt gc.
Click to expand...
Click to collapse
Although in System.gc()'s defense I've always observed that it was run immediately in Sun's ref. implementation. Not sure about Dalvik.
But overall I agree with your conclusion.
cyansmoker said:
I am still impressed that you can write Android games using these techniques. Is your game low-res or is Dalvik that powerful?
Click to expand...
Click to collapse
So far I have not been having any performance issues. The ArrayLists contain GameObjects which are quite lightweight memory wise as they do not contain Textures.
Textures are maintained in separate dictionary with a string key.
I did try recycling GameObjects in one location where I was spawning / destroying a lot but it didn't really seem to impact performance much.
I think my biggest area for optimisation at the moment is in collision direction. Currently there are about 5 different ArrayLists (Obstacles, Enemies, Players, Player Bullets, Enemy Bullets etc) only those that interact are tested for collision (Vector2d distance < objects collision radius). I think theres probably opportunity to split it further into quads.
I've yet to build in proper optimisation checking but it plays fine in 320x480 with ~100 enemies on screen and 4 player ships with maybe 20 bullets on screen at once with a turnover of 5/10 GameObjects a second. Even with this number though Texture memory usage is low with most enemies between 16x16 and 48x48.
I think libgdx and the behaviours library I use are pretty optimised.