1

Suppose I have a reference to an instance of a class, which doesn't have any direct/indirect reference to problematic objects (like context,views,...). Are there any differences between using this reference in a static reference and using it inside the class that extends the Application class?

I mean, in both ways the referenced object will be freed only when the process is killed (or when there are no references to it), right? Maybe there is a difference when using multiple processes?

halfer
  • 19,824
  • 17
  • 99
  • 186
android developer
  • 114,585
  • 152
  • 739
  • 1,270

2 Answers2

1

One slight difference is that the Garbage Collector will first destroy static references bound in Activities (or Services) in case of intense memory shortage if it was in a situation of choosing between a static reference and a reference inside Application class. This situation happens because when the Activity (or Service) is destroyed, it will leave the static variables without references (if they have no other reference except the one described above), so they can be collected by the GC. Even if the VM reinitialize the Activity (or Service), those static references will take the initial value losing any updates that may have been occurred. As a general rule of thumb, if you want to be sure that the static variables will be persistent:

  1. Do not reference them from Activities (or Services) since there is a chance that they might be destroyed in case of memory shortage.
  2. Reference them from Activities or Services but handle the situation of them being destroyed manually (for example, with the onSavedInsanceState method of Android) just like will you do with non static references.

EDIT Here is an explanation of why is this happening:

Static references are bound to the class loader of the class that first initialized them. This means that that if a static variable inside any class has been initialized by an activity, when that activity is destroyed also its class might be unloaded and so the variable becomes uninitialized. While if the variable is initialized by the application class, it’s life is the same as the application process so we’re sure that it will never become uninitialized again. That’s why I chose to initialize all the singletons in the MyApplication class.

found in this link.

AggelosK
  • 4,313
  • 2
  • 32
  • 37
  • really ? can you please give a link of where you've read about it ? also , why does it occur? isn't it totally opposite to how it should work on java "world" ? – android developer Jul 12 '12 at 08:03
  • i see . what if the java file of the class has the static reference ? i mean , if it's not inside an activity class , but on its own ? is it also possible that such a reference be null-ed ? also , is there a more official text about this issue made by google? – android developer Jul 12 '12 at 08:38
  • I cannot give a definite answer but i believe the same behaviour as described in my answer will occur since the application context refference life span is the same as the apps life span but it is possible for `GC` to clear static references inside a static class in times of intense memmory usage. I could not find a more official document by google describing this issue. I just mentioned this issue since i heard quite a lot of programmer complaining about having their static references cleared sometimes and i found it usefull to keep in mind. After all there is a logic explanation around this. – AggelosK Jul 12 '12 at 08:59
  • i didn't mean static class . i meant normal public class which has nothing to do with android , for example , a class that has an int inside it. if within this class i have a reference to this same class's instance , the same weird rule will work on it too (meaning that the reference might be null at some point) ? – android developer Jul 12 '12 at 11:42
  • I believe this is a different matter and i am not sure if the same rule will aply since you will have an instance of that class and where the reference of that insance is located defines the life span of that instance, in other words, the instance of that class depends on instance or static class that holds the reference. For example, if you have that reference inside an `Activity` the life of that instance depends on the life of the `Activity`. – AggelosK Jul 12 '12 at 12:05
  • and if the class is a simple class ? what would be its lifespan then? – android developer Jul 21 '12 at 20:35
  • i've found this link which says that static references are never null-ed unless the process is killed: http://stackoverflow.com/a/5105220/878126 . i really have no idea what is the truth now . isn't there any official place to read about this behavior in order to decide when it's ok to use static references and when it's not ok (other than referencing to "bad" things , like activities and such) – android developer Jul 21 '12 at 20:46
  • Honestly, i do not believe that if you use static references, you will have to deal with the problem that i described. A general rule is that this problem can only occur if you have your static reference in an Activity (or Service) and the VM need to kill this Activity to free up memmory. The same goes for objects of classes if their only reference is in an Activity (or Service). In my opinion, if the GC comes to this place (to destroy Activities), your first concern should be to do better memmory handling and not the static references. I apologize if my answer caused more confusion than help. – AggelosK Jul 22 '12 at 09:17
  • i see . thank you. please edit your original answer and add there a summary , so that i could tick this answer as correct. – android developer Jul 22 '12 at 09:40
  • I have updated my answer. Feel free if you want to suggest any complementary edits. – AggelosK Jul 22 '12 at 10:45
  • but that doesn't seem like the same thing as written by the link i've given : they say there that static references live as long as the process , and this can occur only if you've closed all activities & services. they say that classes are not being unloaded . this is very strange to me that there is no consensus of what can occur . the guy (or company) that wrote it (CommonsWare) has a lot of reputation so i think more explanation should be added. – android developer Jul 22 '12 at 15:44
  • Seeing the link you provided, i am not tottaly convinced that CommonsWare answer is the correct one to be honest. In my opinion, you better add your own answer to your question so that both opinions are displayed. Also if you want i can delete my answer. Again, i apologise for the incovenience since it seems that my answer mostly confused than helped:) – AggelosK Jul 24 '12 at 07:39
  • Also sorry for the late response, i was looking for any documents or paper from Android that can back up or disproof my suggestion but i could not find any. – AggelosK Jul 24 '12 at 07:43
0

I believe the article cited in the other answer by @Angelo is very wrong (to say the least) and caused much confusion : the classes in android are unloaded on a per process basis not on a per class basis. That is if your app is killed and the classes are unloaded you lose all static state - if not no. That is what I make of @fadden's answers at least :

Is it still the case that Android never unloads classes?

Android: When do classes get unloaded by the system?

Now your question is a bit vague... A static reference is not the same as a non static wherever it's used. If you mean that both variables are static then there is no difference if they are in an activity, application or whatever instance - whenever the class is loaded and the variables take some value they will remain so till the classes are unloaded. Not sure if there is a specified order in unloading the classes - or if that would matter.

Community
  • 1
  • 1
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • no, my question was based on the fact that you can extend from "Application" class, and put the variables there, instead of putting them in static references. the reason that it's possible is that there is only one real instance of this class and it lives for a single process till the process is killed, much like static references. – android developer Nov 08 '13 at 19:03
  • @androiddeveloper: "there is only one real _(??)_ instance of this class and it lives for a single process till the process is killed" --> I am so unsure about this I went ahead and [asked](http://stackoverflow.com/questions/19365797/androids-basic-components-class-loading-java-objects-lifecycle) – Mr_and_Mrs_D Nov 08 '13 at 19:09
  • I had only once time that the onCreate of the application was called after something else has happened (i think something with a broadcastReceiver, but i'm not sure). however, as far as I know , there is only one real instance of the Application class per process. by "real" i mean that since you can always do "new App()" and use it, but Android will use for your app only the instance that it has created itself and called its "onCreate()" method. – android developer Nov 09 '13 at 11:23
  • Might have been a content provider (see the [docs](http://developer.android.com/reference/android/app/Application.html#onCreate%28%29)) - but where is the "singleton" property _documented_ ? And where is the guarantee it is destroyed _last_ ? – Mr_and_Mrs_D Nov 09 '13 at 12:44
  • yes i think it is a content provider. even the docs say about it: http://developer.android.com/reference/android/app/Application.html#onCreate%28%29 . there you can also see some clues about the applicaton act as a singleton (since it's an alternative to static references). – android developer Nov 09 '13 at 14:17
  • You said "(i think something with a broadcastReceiver" - so it was a Content provider finally ? The final answer is the source but I really can't go through this now – Mr_and_Mrs_D Nov 09 '13 at 14:52
  • yes it was something that i don't usually use, that's why i didn't remember. it's probably the content provider. i don't understand your last part of the comment. – android developer Nov 09 '13 at 15:19
  • @androiddeveloper: yes sorry - I mean the source to see where the Application is instantiated - but should be quite come digging. Will remove the last comments not to clutter this up – Mr_and_Mrs_D Nov 09 '13 at 17:14
  • you don't have to. maybe people who read this will understand better what i've meant. – android developer Nov 09 '13 at 22:49