freeing shared resources in Android app

2019-07-02 15:44发布

问题:

I'm writing an Android app that has both an Activity and a Service component. Furthermore, I've got a class encapsulating a resource that I am sharing in several places across both the Activity and the Service. My question is how I can figure out when to free the resource. As I understand it, Java does not have a notion of a destructor, so I can't just create a destructor in the shared object which will be called when there are no more references to the object. Android has functions such as onPause for the Activity, and onDestroy for the Service, although technically there is no guarantee that either of these functions will be called under all possible shutdown circumstances (e.g. the low memory killer won't call these functions). And in any case, it is possible for the Activity to be destroyed without the Service being destroyed, in which case there could still be references to the resource, so I can't just blindly free the resource in that case either.

Since Java does not have a destructor, some sources say to create one's own "close()" type function and call it manually. But it seems like for this to work I would have to maintain my own reference counting scheme, and this seems rather strange considering that Java already has GC which should eliminate the need for such a scheme.

What's the proper solution here?

回答1:

The answer is no.

You would have to remember to clean up such things as closing files etc on your own but even objects which does not do proper cleanup will rarely cause memory leaks, as they cannot perform any actions or take up space if GC sweeps em away. Which it will, unless you explicitly do something to keep it alive.

The only places that can be of concern, in my mind, are static objects, calling C code and passing huge objects between classes. If you do a fair amount of spaghetti, circular referencing, code, risk is that GC will not collect the objects, as there are still references to them.

As long as you create somewhat sane code, you will be fine. DON'T PANIC



回答2:

Java like c# is a managed language instead of c. It implements garbage collection that is responsible of managing objects. When an object is no more necessary it will be automatically destroyed. Don't care to free memory manually.



回答3:

Java do not have destructor but finalize() is their with every object which kind of work like destructor.

For standard in memory object do not worry much, java will automatically destroy those when not referenced in another class. This has nothing to with Android and it standard Java stuff.

If you have costly resource, which is expensive to create, you might think of persisting it on on disk using serealizable. if you do not want to persist, you can think of Java reference to keep it alive for long time. In this scenario, you can also think of a singleton design pattern to have more control on expensive objects. None of these contradict with standard Java Garbage collection where GC destroy object which are not actively referenced.

When your object is jumping from activity to activity make sure that this type of object stay separate of any activity and do not hold reference of an invisible activity. With all these view objects activity are too big for Android to carry around specially when they are not visible.

However on older Android version Bitmap memory allocated on native layer and they will not garbage collected without calling recycle.

if you create a bound service and keep your object on that service, Android will keep that service alive as long as a active connection remain.