I have some memory problems about my android appwiget,
(It's small toy appwidget based drawable animation repeat)
So I watched my memory viewer in Android Studio.
I found my app's memory increased at initial time, but when it doesn't enough memory it automatically release some memory.
I want to know what android function make this.
Can I control this release function with java code?
*I tested at real device android ver 4.42
You are talking about Garbage Collection, which is the process of removing from the memory the objects that are no longer required. You can have a good idea of how it works in Java here.
In Android (and Java in general) you can suggest the virtual machine to do it with the System.gc() call. Note, though, that it:
Indicates to the VM that it would be a good time to run the garbage collector. Note that this is a hint only. There is no guarantee that the garbage collector will actually be run.
Related
I'd like to know some simple code that allows for freeing used memory that is no longer needed, in a similar way as a lot of memory freeing apps do.
Yes, I'm aware that this shouldn't be neccesary because Android manages memory on its own, but it looks like what's causing a non desired behavior in my app is having a lot of opened app occupying memory, so I think this is worthwhile to try, and check if the error happens any longer.
Could anyone hand me such a code? I'm not able to find any.
What I gather from the article is that you don't need to do anything to reclaim memory, but you can make garbage collection happen quicker and at specific times. What this means to me is that any arrays, Lists, large objects, etc. should be set to null when you are done with it. Granted, this should be done automatically when you leave a method or a View, but in case you are in a long running loop or staying on a page with lots of data hanging around, you can clean it up a little faster.
The Android Runtime (ART) and Dalvik virtual machine use paging and memory-mapping (mmapping) to manage memory. This means that any memory an app modifies—whether by allocating new objects or touching mmapped pages—remains resident in RAM and cannot be paged out. The only way to release memory from an app is to release object references that the app holds, making the memory available to the garbage collector. That is with one exception: any files mmapped in without modification, such as code, can be paged out of RAM if the system wants to use that memory elsewhere.
https://developer.android.com/topic/performance/memory-overview
You can also check your memory usage to see if that's really the problem. This is linked in the article above, but I thought I'd pop it out so it's easier to notice.
https://developer.android.com/reference/android/app/ActivityManager.html#getMemoryClass()
I am trying to understand where my app is using memory, and where I can make it more efficient in this respect.
In the Android Monitor part of Android Studio, I have dumped the Java Heap, and am looking at the generated hprof.
And I see a lot categorized under FinalizerReference:
What is this? How can I understand better what is causing it, and how to keep it down? Looking into the "Instance" panel doesn't help me much... doesn't make much sense.
I have tried looking at this but it's all slightly over my head at the moment.
Also, at the moment the memory monitor is reporting (in the live chart section) an Allocated memory of 10.58 MB. But on my device, in Application Manager > Running Processes, my app is showing a memory usage of 44MB. Why the discrepancy? If it's the ~33MB I want to try and reduce, I'm not apparently even seeing that in Android Studio, so no real hope of identifying what it is?
There may not be much you can do about FinalizerReference memory usage. See this question for more details - basically some objects implement finalize() and these are handled a little differently, such that they can end up sticking around longer. I haven't looked into it too closely, but I suspect that some android sdk objects do this and there's little you can do about it except for maybe tuning up your object caching/recycling to reduce it.
I'm not sure if this would help with FinalizerReference, but one thing I like to do to track down memory leaks is to find suspicious objects' connections to the GC root.
If you're using the Eclipse hprof analyzer (independent of the actual Eclipse IDE; works with hprofs generated by android studio), this is one way to access this:
Overview
Histogram
Right-click, "List Objects"
Right-click an object you suspect is leaking, "Path to GC Roots"
Now you should see a list of nested references leading back down from the gc root to your object.
I'm not exactly sure what is owing to the discrepancy - here is a similar question on that. Apparently the memory monitor tool may only be reporting heap allocations made by Java code, whereas the device reports the entire processes's memory usage.
The Retained Size reported by the Memory Profiler for FinalizerReference is currently a meaningless number, as I argued in my answer to my own similar question.
To summarize: Treating FinalizerReference like any other class when profiling (as Memory Profiler does), leads to repeated counting of the same memory when calculating its Retained Size.
I view this as a bug in Android Studio's Memory Profiler, and have filed this issue.
Good day,
I am developing an adventure game in AIR for Android. I am instantiating levels from the library (movie clips), each containing at least one HD resolution bitmap.
When the game starts, it occupies about 150MB of memory, including the AIR runtime and the SWF. Out of this 150MB the SWF is about 12MB at this time.
As the game progresses the memory consumption of the AIR runtime increases, while the memory used by the SWF remains at around 15-20MB. When the total memory consumption reaches about 350(!)MB, the OS intervenes and kills the app.
I was careful to reuse objects whenever I could, and nullify any unused objects to make them eligible for GC. GC seems to be working as it should, as the memory used by the SWF remains steady around 15-20MB. I can see it drop from 20 to 12 from time to time when GC kicks in.
Things I've tried:
Removed all cacheAsBitmap and cacheAsBitmapMatrix properties.
Exported each level into a separate SWF and loaded them from there instead of the library.
Forced the GC hack just to see if it has any effect.
Fiddled with System.pauseForGCIfCollectionImminent(n) with different values for n.
Tried different acceleration modes (direct and auto) thinking maybe the GPU is at fault.
All failed, memory consumption just runs away.
This happens only on Android. On a PC everything is fine, the whole thing takes up about 250-300MB, and this number remains steady, no matter how many levels I load one after another. Didn't have the chance to test on iOS yet.
I would really appreciate any ideas or insights into how to make this problem go away.
Thanks.
1) Easiest way to find memory leak is to use Adobe Flash Builder. Just run profiling.
2) Also good way to exclude leaks in future: create function which will be used for "cleaning". E.g. it will null all local variables of instance and so on. Something like usual c++ destructors. Then, before nulling your object, just call this method.
I have two problems:
1.What is trigger conditions of LOW_MEMORY and OUT_OF_MEMORY in android memory automatic cleaning mechanism?
I check the reference LOW_MEMORY is done automatically every once in a while, and OUT_OF_MEMORY is conducted in system out of memory. Is this right? If it is right, is the recovery of memory strategy the same?
2.What conditions perform memory of the recovery in android task manager?
The detail condition is testing phone memory 512; the user available memory is 230. The visual inspection is 50M. It can trigger the memory recall in 20M. That is to say 50M and 20M are the stable memory. But sometimes it has not the trigger recycle when the memory less than 3M.
Is the trigger recycle need special condition? Where the trigger recycle code should be put?
In android is each application has fixed memory limit.. it change from device to device... for ex if phone memory is 512.. and app memory will be 30 to 50 mb if your app cross using this memory it will get crash...
onLowMemory is the method in the activity.. it notifier when memory is low... it is like warning .. OUT_OF_MEMORY is exception which you cant handle(catch)..
OUT_OF_MEMORY exception max raise normally when we deal with bitmap...
Garbage collector is available in android also but when we deal with bitmaps it may fail in some cases.. for bitmap we are responsible to recycle..
my android application works well but it's performance(speed) is slow. In my logcat i saw frequent garbage collection operation like
11-02 15:07:20.647: DEBUG/dalvikvm(12571): GC freed 295 objects / 38448 bytes in 93ms
Is this the reason for low performance?? How can i improve my applications performance???
anybody please help
If you use the emulator don't worry - it is slow by itself. GC is not responcible for this i think, 93 ms is time you won't even notice. So try your application at the real phone and if there are preformance issues - use the profiler.
Your application performance in terms of user interface and memory is quite related.
In this case 93ms means that your device could be dropping about 6 frames in the ideal scenario. If the GC is executed often this could be a problem.
The Android ART/Dalvik virtual machine is a version of the Java Virtual Machine where the Garbage Collector implementation is based on generations. This means that your application process has a heap associated separated by different generations where the GC is going to act once a generation is full. You can think of these generations as buckets or arrays of memory.
Once a generation is full the Android virtual machine will start the garbage collector process. As the Android virtual machine can not collect and fragment your application heap while the app process is running the garbage collector event will stop all the threads in your app while the garbage collector is working. That's why your application can be dropping frames if the app garbage collector is invoked so repeatedly.
Here you have an example:
Last week I discovered my app was leaking memory. I discovered this because after 20 minutes using my app I noticed the UI was performing really slow. Closing/opening an activity or scrolling a RecyclerView was really slow. After monitoring some of my users in production using http://flowup.io/ I found this:
The frame time was really really high and the frames per second really really low. You can see that some frames needed about 2 seconds to render :S.
Trying to figure it out what was causing this bad frame time/fps I discovered I had a memory issue as you can see here:
Even when the average memory consumption was close to the 15MB at the same time the app was dropping frames.
That's how I discovered the UI issue. I had a memory leak in my app causing a lot of garbage collector events and that's was causing the bad UI performance because the Android VM had to stop my app to collect memory every single frame.
Looking at the code I had a leak inside a custom view because I was not unregistering a listener registered into a Android Choreographer instance. After releasing the fix, everything became normal :)
If your app is dropping frames due to a memory issue you should review two common errors:
Review if your app is allocating objects inside a method invoked multiple times per second. An example could be creating new instances of an object inside a onDraw custom view method.
Review if your app is registering an instance into the Android SDK but not releasing it. Registering a listener into a bus event could also be possible leak.
Disclaimer: The tool I've been using to monitor my app is under development. I have access to this tool because I'm one of the developers :) If you want access to this tool we will release a beta version soon! You can join in our web site: http://flowup.io/.
If you want to use different tools you can use: traveview, dmtracedump, systrace or the Andorid performance monitor integrated into Android Studio. But remember that this tools will monitor your connected device and not the rest of your user devices or Android OS installations.