尽量不要使用static静态变量!!!

使用静态static静态变量潜在性问题:
①占用内存,并且内存一般不会释放。
②在系统不够内存情况下会自动回收静态内存,这样就会引起访问全局静态错误。
③不能将activity作为static静态对象,这样使activity的所有组件对象都存入全局内存中,并且不会被回收。

静态变量的生命周期:
①类在什么时候被加载?
当我们启动一个app的时候,系统会创建一个进程,此进程会加载一个Dalvik VM的实例,然后代码就运行在DVM之上,类的加载和卸载,垃圾回收等事情都由DVM负责。也就是说在进程启动的时候,类被加载,静态变量被分配内存。
②静态变量在类被卸载的时候销毁。
类在什么时候被卸载?
在进程结束的时候。
说明:一般情况下,所有的类都是默认的ClassLoader加载的,只要ClassLoader存在,类就不会被卸载,而默认的ClassLoader生命周期是与进程一致的。
③Android中的进程什么时候结束?
这个是Android对进程和内存管理不同于PC的核心——如果资源足够,Android不会杀掉任何进程,另一个意思就是进程随时可能会被杀掉。而Android会在资源够的时候,重启被杀掉的进程。也就是说静态变量的值,如果不做处理,是不可靠的,可以说内存中的一切都不可靠。如果要可靠,还是得保存到Nand或SD卡中去,在重启的时候恢复回来。
另一种情况就是不能把退出所有Activity等同于进程的退出,所以在用户点击图标启动应用的时候,以前存放于静态变量中的值,有可能还存在,因此要视具体情况给予清空操作。

Application也是一样不可靠。Application其实是一个单例对象,也是放在内存中的,当进程被杀掉,就全清空了,只不过Android系统会帮重建Application,而我们存放在Application的数据自然就没有了,还是得自己处理。

④静态引用的对象不会被垃圾回收。
只要静态变量没有被销毁也没有置null,其对象一直被保持引用,也即引用计数不可能是0,因此不会被垃圾回收。因此,单例对象在运行时不会被回收。

1.static类使用场景-单例模式:
java中经常会使用单例模式,单例模式保证内存中同一时间只有一个类的对象,如:

public class AutoTestModuleManager{
 private static AutoTestModuleManager mAutoTestMdManager = null;
 private Map<String, AutoTestModule> mUiList = null;private AutoTestModuleManager() {
 Log.w(“test”,“AutoTestModuleManager”);
 if(null==mUiList){
 mUiList = new HashMap<String, AutoTestModule>();
 }
 mUiList.clear();
 }
 public synchronized static AutoTestModuleManager getInstance() {
 if (null == mAutoTestMdManager) {
 mAutoTestMdManager = new AutoTestModuleManager();
 SkLog.e(“getInstance”);
 }
 return mAutoTestMdManager;
 }
 }


单例模式就是使用static 类,上述代码的getInstance获取AutoTestModuleManager 的单一对象。还有一种称为双重检查锁定的单例模式。
 
2.android中使用static类易出现的问题
在android中使用static类需要注意,如果apk退出时程序员未主动释放static类,将造成内存泄漏。如上述AutoTestModuleManager类,如果在activity中调用,当activity onPause-》onStop-》onDestory退出后,AutoTestModuleManager静态对象并没有被销毁,这时如果再次进入activity,会发现AutoTestModuleManager的构造函数并没有被执行,也就是说AutoTestModuleManager静态对象没有重新生成。
出现这种问题带来的不仅仅是内存泄漏的危害,对我们的程序运行逻辑也是有意料不到的影响。比如我们在activity中调用静态类,希望在activity调用的时候能初始化该类,但是如果activity退出的时候没有释放静态类,当再次启动activity时,静态类没有初始化,而是沿用的上一次的,这样就会带来问题。
 
3.解决办法
在使用静态类时要注意使用完后释放,如上述AutoTestModuleManager类中,增加release接口:

public synchronized void release(){
 if(mUiList != null){
 mUiList.clear();
 }
 mUiList = null;
 mAutoTestMdManager = null;
 }


activity中使用完AutoTestModuleManager后调用release()即可。