Google Map View is leaking very much - android

I've previously used the MapFragment, but it was slow for my needs. The MapView is almost instantly and fits my needs exactly. But there is one thing they both have in common:
Huge memory leaking.
I've 'destroyed' the MapView like I should when exiting the activity and it still leaks. The MapView is in an activity that is frequently opened and closed and opened quickly again. Could that be the issue?
Here are some screeenshots of my hprof files (I'd rather not upload the hprof files, due to possible sensitive information):
I've had multiple leaks, and they al point to the same classes.
However, I am using a custom class, which is unneeded at this moment, and I'll revert back to the default MapView.

I am not sure if that's the case, but I did something stupid using Kotlin.
Kotlin got null-safety.
googleMapView?.onDestroy()
I called that in onDestroy() of my Fragment. Guess what? googleMapView was null, that's why it didn't call it's onDestroy()! Wasted around 2 hours on this, because I thought some of my custom classes kept references or other things that led to this...

Related

How much Fragmentation can be optimized before breaking the application

Recently on the app I have started working, I thought to go full OOP and try out Fragments to make the UI most flexible and reusable as possible.
At least that was the plan.
Here is where I encountered some issues.
I have a BottomNavigationView in my app that has four tabs. Therefore, 4 different fragments.
HomeFragment
InboxFragment
FavoritesFragment
ProfileFragment
I believe, if I'm using bottomNavigationView, this much fragmentation is unavoidable.
Then when I started to fill out the HomeFragment with content, I find that the file is getting too complicated and huge to easily examine specific parts. This is where I get the idea to create fragments of features that may get used in other activities/views.
So, one such individual fragment is AdvertisementFragment.
Here's where things get interesting. AdvertisementFragment uses code that employs Timer.schedule/Thread.sleep; something to delay a certain function called update.
But the code wasn't being delayed, it sped up instead. Checking the Logcat showed messages like
Frame time is 8.006377 ms in the future! Check that graphics HAL is generating vsync timestamps using the correct timebase.
OR
Skipped 2 frames! The application may be doing too much work on its main thread.
I only create the dummy apps for my employer, i.e. If you will, say a "working" demo. I'm just a UI designer for them.
Now when I saw these messages popup in my logcat, my first thought was to experiment, how much my device can take before the app crashes. I frantically click away on the four tabs of my bottomNavigationView and sure enough I see the first problem.
Nothing is being loaded in the fragments, its just a white background. All the components, Fragment or Not, weren't showing up, in any of the fragments. Then after a few more seconds it crashed. I test the same on two physical devices, and sure enough, it was not the emulator that crashed, my code was the problem.
Even though, it is not my job for optimizing the code, it is going to be a real pain for the developers/users of the app, for the mess that will emerge out of my faulty working model. Hell, if the developers had to redo that, it's going to be more costly.
Which is why, I'm here, is using Fragments within Fragments a good idea? I know about saving Fragment states, but can severely Fragmented code be a nuisance to the memory and optimization? If you are talking about saving states of every fragment then would it not consume more memory?
Say, I have a HomeFragment, InboxFragment, etc, from above, which I load into MainActivity. I can switch between these parent fragments with a bottomNavigationView. Say, HomeFragment itself has 3-5 fragments and rest of the code in HomeFragments is specific to HomeFragment. In other words, let's assume that 40% of code in HomeFragment is Fragments, and the 60% is code specific to HomeFragment. How does that impact performance? What if other parent fragments (InboxFragment, ProfileFragment, etc) have similar constitution of Fragments and Activity specific code?
Can this much Fragmentation be easily/somehow optimized? Or is it outright bad practice?

Is nullifying every views and listeners a good idea in finding or correcting leaks?

I am working on a project and I keep seeing methods that nullify the views and listeners on every onDestroy(). I have even seen code that navigate the rootView and set every listener to null.
The original coder told me that he has done it that way to prevent leaks, but I think it is causing more harm to the VM. What do you think?
In my opinion, it is unnecessary. Once the activity is destroyed (i.e. onDestroy is called) then all the views and its related listeners are qualified for garbage collection.
However, make sure you are not treating anything static with activity and/or anything that is bound to activity's context (that includes Views too).
Most Android-related memory leaks are related to incorrect usage of event buses (forgetting to unsubscribe something), or from implicit reference to a context (public class Blah extends AsyncTask<?,?,?>), or static reference to the Activity (because who knows why, everybody knows that's a terrible idea).
Nulling out your views won't help you find any of that.
You can however use LeakCanary library which traces memory leaks for you automatically.
It may cause the GC to make the used memory be reuseable faster, but its not something i would do since its tedious and a waste of time.
If you want to prevent memory leaks you should used tools like LeakCanary or MAT or alike, or\and be well aware of diffrent Android components lifecycles and know what you are doing when using static variables. It is less likely that that guy avoided a memory leak, unless he references Android components in static fields (which is a bad idea anyway).

Android vs configuration changed

I apologize for my English but translated with google. I'd like to understand why Google with Android restarts the activity at each change and you lose all the data displayed. How do you solve this problem? Could not they make it optional this thing?
On every forum I read to use the methods onSaveInstanceState, onRestoreInstanceState, onConfigurationChanged, but how to use them is not explained well. If I have a complex application, with many objects, with EditText, with Markers, Polygons, I'm forced to save everything by hand with temporary variables? There is another way faster and easier to do it? Do you have any practical example to show me? I hope you know help me understand, thank you all.
It is an optional thing. In your manifest, add android:configChanges="orientation|screenSize" to your activity and it will turn off that behavior.
Really there's only 1 good circumstance to not override it- if you have no AsyncTasks, no Threads, no Loaders, no bound services, AND you have separate layout.xml files for landscape and portrait. That's about the only time it doesn't cause more pain to recreate than it saves. It's google's biggest screwup in the API.

How to solve memory leaks , Is useing service a option?

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.

Memory from activities not released

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.

Categories

Resources