Programmatically clear cached background process - java

I've developed a simple application that loads four mobile webviews side by side.
On a fresh install the app fully opens and loads these pages in under 0.5 seconds.
However if i minimize this app, for some reason its "cached background process" is over 200mbs! sometimes 250... Seems completely unnecessary as the app loads lightning fast on a fresh install
How can I clear this cache when the app is minimized (onbackpressed etc)

You need not to worry about cached memory as system will reclaim it when required.
however if still you want to do something about it you can call finish() in your onStop() method.
also this is a great answer on this topic by CommonsWare.
"cached background processes" usually refers to processes that do not
have a foreground activity and do not have a running service. These
processes are kept in memory simply because we have enough memory to
do so, and therefore, as you note, the user can switch back to these
processes quickly. As Android starts to need more system RAM for yet
other processes, the "cached background processes" tend to be the
processes that get terminated to free up system RAM

Related

Memory allocation problems with android application

I have an android application that performs image analysis, which is managed with an IntentService - the process takes a couple of seconds each time and works accurately and quickly.
But when the process is repeated in the app around 50 times (as illustrated) it begins to get very slow until the point in which the app and device becomes unusable. When the device is restarted and app opens again it runs as usual.
Inspecting with Android Studio I can see that each time I run the analysis that the memory allocation for the app goes up and up every time by around 1MB. So it is clearly running out of memory when it crashes.
I have used this flag on finishing the analysis and going to the result to try fix background activities;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
which has had minimal effect, and I understand the IntentService manages itself shutting down. So not sure what else I can do to try and reduce the memory allocation or at least clear down allocation and stop adding to it?
Further details:
The application is using the camera implementation based on Google Camera2
The analysis is done with a C++ library through the IntentService
It seems you are not handling the resources (variables, image files,etc) properly, and its creating memory leaks in your application.
you can find here in this blog Written by Johan on handling the memory leaks in your application or see this SO Question.
Avoid memory leaks on Android
If the memory leaks are being generated in the c++ library then you can easily find the resource which is leaking the memory in debug mode.
After the result activity you should call the garbage collector as suggested by Grisgram and close any unused resources.
It would be good if you could provide the stack trace in the question.
Try using leakCanary https://github.com/square/leakcanary to find out what is causing the leak and use a weakReference https://developer.android.com/reference/java/lang/ref/WeakReference.html to allow it to be garbage collected when necessary. It may also be that the device you are using does not have enough memory to hold 50 high res images in memory at the same time. You could try lowering the resolution of the images if you are keeping them in memory and be sure you are recycling bitmaps https://developer.android.com/topic/performance/graphics/manage-memory.html
I would also consider using a threadPoolExecutor instead of an intent service, they are much more configurable https://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html
I wanted to add something to Ali786's answer.
Intent Services are not really the best choice for something that is going to repeat itself. The next time you call the service it goes into a queue.
Intent Services work like HandlerThreads. They have their own MessageQueues and after you start the service with Intent it will wait for the previous one.
Normal services which run on the UI Thread are running in parallel.
I am not sure if you are doing something after you send the information of the analys to your activity, but if you do, the intent service will not die and the next one will have to wait. Intent services are not the best choice for communicating with your UI Thread, Asynctask might be better in your case. If you give us some more information (code) maybe we can give you a more accurate answer.
Hope this helps!
One thing may be it happens like this, If your working intent service after job complete may be your not destroy the service
Check in settings running service list for running service of your app

Making two threads to continue running in background

I'm writing an android app that involves one AudioTrack and one AudioRecord. They run in two different threads, and both of them need to continue to run and not being killed when low memory/CPU even if the app is running in the background. I searched about this and I know I could probably use AsyncTask (just like in music streaming app). However, I'm no exactly sure how to do it because the thread that runs AudioTrack is first created (once a certain button on the main activity is pressed), then this thread will create another thread that runs AudioRecord (by creating a Runnable).
I searched about this and I know I could probably use AsyncTask (just like in music streaming app)
No. Your issue is not the threads, but the process.
both of them need to continue to run and not being killed when low memory/CPU even if the app is running in the background
Strictly speaking, that is not possible. The closest that you will get will be to use a Service that in turn uses startForeground() to indicate that it has foreground priority. That will minimize the probability that Android will terminate your process due to low memory conditions, but it will not eliminate it.
Also, please note that you will need the CPU to be powered on to perform your audio tasks. That, in turn, will require a WakeLock. This is going to seriously hammer the user's battery, to the point where you should advise users to keep the device on a charger. That will be particularly important in the future, where the "Doze mode" of the upcoming "M" Android release will block your use of WakeLocks if the device is idle, unmoving, and not on a charger.

Android Service taking up huge amount of memory

Here's how my application works:
The Launcher activity starts a service in the foreground which monitors clipboard changes and fires up the launcher activity everytime a specific kind of string is copied. I'm new to Java programming, I've tried to use all the best practices in the application(using worker threads and keeping the UI thread from hiccupping) and so far everything is butter smooth. The problem is RAM consumption, on a fresh start of the app(after Service is started) the app reports 24M memory consumption in the android running processes. Here's where the erroneous behavior lies:
- The Memory Monitor in Android Studio reports something else
- So does the adb shell dumpsys meminfo mypackage command
Screenshots of both have been attached
These behaviors are incomprehensible for me. 50M is a lot of RAM. Also whenever the Launcher activity is launched by the Service, the app consumes around 1M more memory than it is already using. Can anyone help me debug this?
Thanks
The problem is likely a result of how Android handles Services and
Activities running in the same application process:
As long as a (started) Service is running in the process, the "memory
priority" of the whole process is elevated above other processes that
are only running (background) Activities.
However, since Activities
are never recycled by Android even under memory pressure (contrary to
some statements in the official docs),
this effectively keeps your Activity alive much longer than necessary. This is essentially a shortcoming of Android's process model.
If your memory usage drops to a few megabytes after you force-kill your application process (and Android subsequently relaunches your Service), or if the memory usage is different depending on whether you leave your activity by pressing the home or back button, this confirms that you are facing this problem.
If you really depend on your Service continuously running in the background and want to minimize memory usage, you could try to move it to its own process (where memory-intensive UI resources like Views in Activities would never be loaded).
Of course, this also increases overhead; you might be better off by just keeping your implementation the way it is. Android will still kill your process under memory pressure, and will later relaunch your Service (but not your Activities), which will minimize your memory usage without any intervention.
Save the heapdump as a HPROF file and convert it to an extension that Java Profiler can read
Then you will be able to see what is using so much ram

How to listen to GC events in Android

Is there anyway we can monitor GC events as they happens in Android?
In Java, I believe we can listen to the events http://www.fasterj.com/articles/gcnotifs.shtml
But java.lang.management APIs are not available in Android.
Why you want this listener. If you simply want to know if your app is running out of memory just check this:
Release memory as memory becomes tight
During any stage of your app's lifecycle, the onTrimMemory() callback also tells you when the overall device memory is getting low. You should respond by further releasing resources based on the following memory levels delivered by onTrimMemory():
TRIM_MEMORY_RUNNING_MODERATE
Your app is running and not considered killable, but the device is running low on memory and the system is actively killing processes in the LRU cache.
TRIM_MEMORY_RUNNING_LOW
Your app is running and not considered killable, but the device is running much lower on memory so you should release unused resources to improve system performance (which directly impacts your app's performance).
TRIM_MEMORY_RUNNING_CRITICAL
Your app is still running, but the system has already killed most of the processes in the LRU cache, so you should release all non-critical resources now. If the system cannot reclaim sufficient amounts of RAM, it will clear all of the LRU cache and begin killing processes that the system prefers to keep alive, such as those hosting a running service.
Also, when your app process is currently cached, you may receive one of the following levels from onTrimMemory():
TRIM_MEMORY_BACKGROUND
The system is running low on memory and your process is near the beginning of the LRU list. Although your app process is not at a high risk of being killed, the system may already be killing processes in the LRU cache. You should release resources that are easy to recover so your process will remain in the list and resume quickly when the user returns to your app.
TRIM_MEMORY_MODERATE
The system is running low on memory and your process is near the middle of the LRU list. If the system becomes further constrained for memory, there's a chance your process will be killed.
TRIM_MEMORY_COMPLETE
The system is running low on memory and your process is one of the first to be killed if the system does not recover memory now. You should release everything that's not critical to resuming your app state.
Because the onTrimMemory() callback was added in API level 14, you can use the onLowMemory() callback as a fallback for older versions, which is roughly equivalent to the TRIM_MEMORY_COMPLETE event.
Here is the reference link https://developer.android.com/training/articles/memory.html
Okay, it will be different for both dalvik and art..
basically you can instruct adb shell to record the GC events in a trace file..
art: https://source.android.com/devices/tech/dalvik/gc-debug.html
It might even be the same adb commands for both art and dalvik.
The memory monitor tool plugs into this when it displays that graphical chart of memory for you in android studio.
Progammatically, probably is harder..look at how FB did their performance tooling as I believe that they are doing the GC event counts from the native C/C++ side and collating them in a flatbuffer for their java side profiling tool code to access..

How to simulate killing of application by Android GC

I need to test serialization\deserialization of application in next cases:
app was in background a lot of time (idle mode) and was killed by GC;
app was in background and was killed by GC by reason of resources (memory\cp) lack;
On some devices it can be simulated by launching 1-2 games.
But on quad-core devices with 1gb memory it's very-very hard with 4-10 heavy games and takes a lot of time.
I try to implement some demo where emulating loading on resources:
create bitmaps arrays
create objects arrays
launch a lot of services
launch a lot of activities
But no result, application still works (even on old devices) and my demo is crashed with OutOfMemoryException.
How can i simulate high load in demo application?
Thanks!
Well, the "GC" is actually abused "Out Of Memory Killer" and that kills the applications as if by signal 9. In rooted device you should be able to invoke kill(1) command from shell or kill(2) function from native library (I am not sure whether it's bound to Java) and kill your application whenever you want.
The system normally calls onStop in the Activity when it's going to background and than kills the application without further warning and without chance to react. So if you leave the application and kill it, it's appropriate simulation of it being OOM-killed.
Install any memory cleaner on play store. I install this : easymemorycleaner
once u cleaned your memory. Your stored variable inside memory will be gone. Unless you stored data in Parcelable. It will be persistent.

Categories