关于内存释放自己的见解

来源:互联网 发布:python面试题 知乎 编辑:程序博客网 时间:2024/05/22 06:08
在最近的编程中出现了大量的内存问题,只要开启软件后就发现内存一直在往上涨,随便点开几个页面就出现卡死的状态,只要在卡死的时候查看内存都发现40M~50M不等,实在令人头疼.
 
        在我找了一个多星期的情况下终于找到了解决内存无法释放的方法
 
1. 首先查看代码中是否使用了静态 
    这个很重要,无论是
    public static final .....常量
   还是
    public static void...... 方法
只要是在Activity中使用均出现无法释放页面的情况
 
解决方法:写一个公共变量类 专门用来存放静态变量
出现这个问题的原因是由于静态变量始终占有着系统的一个内存,而这个静态变量是在Activity中了,导致GC无法对这个页面做释放..所以就出现了无法回收的情况
 
2.查看是否有线程没有关闭
 
例如写了个线程
new Thread(){
private void run(){
while(true){
Thread.sleep(5000);
.
.
.
}
}
}.start();
每隔5秒去做一些事..
 
这个线程在运行期间是正常的,但是在你结束页面的时候就会出现大问题,因为线程一直开着,在结束页面的时候系统并不知道你的这个线程是否需要继续运行,所以就会占用着这个页面,结果可想而知
 
解决方法:
1.把线程写到后台去,让后台做处理,如果需要交互则使用广播
 
2.为线程添加名字,比如
Thread a =new Thread(){
.
.
.
}
 
a.start();
这样的话在页面结束的时候调用
a.sleep(200);
a.interrupt();
就可以结束线程了
 
3.上下文 this 的更换
从网上找了许多资料都说this 也就是我们平常说的上下文Context因为一直被占用所以导致了页面的释放出现问题
在经过了研究后发现主要出现问题的地方在于
 
一.弹出的Dialog
在Android的开发中免不了使用Dialog,但是调用Dialog就必须要调用上下文,而且这个上下文还不能更换
我在测试中发现个很好用来实现这个问题的方法
 
随便写一个工程 里面有5~10个页面
里面只有两个个按钮,第一个按钮是用来跳去第二个页面,   第二个按钮是打开一个Dialog的,如此类推
测试就这样 打开第5个页面 然后打开Dialog 然后按Home 接着打开再按到第四个页面然后Dialog如此类推
结果到第二个页面按完后去查看软件的内存,就会发现内存很恐怖- -||
 
通过这个我们就可以知道打开Dialog后如果按Home会出现页面无法释放的情况,那么这个如何解决?
首先我们需要屏蔽掉系统的Home键
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
 
之后再在ONkeyDown中监听Home
if(keyCode==KeyEvent.KEYCODE_HOME){
dialog.dismiss();
finishAll();//控制关闭所有页面的方法
}
 
二.数据库的调用
 在开发大型的软件项目中免不了要使用数据库,但是使用数据库就必须要使用上下文(-_-|||好熟呀,貌似我刚刚就打过这段话)
在使用上下文的时候可以不用this,而用getapplicationContext() 来代替
这个代码如字面上的意思,是应用的上下文,而平时用的this只是代表当前页面的上下文,两者有何区别??

getapplicationContext()这个上下文使用的是全局的意思,在这个程序运行的时候就启动,在程序结束的时候才关闭

而this只是当前页面的上下文,这个页面结束了也就跟着结束了

其实在使用上两者并没多大区别,只是要注意的就是在Dialog 或者popupwindow中是不可以用全局上下文的.毕竟这些是建立在页面的基础上显示的(纯属个人理解)

好了上面说了那么多也没说出为什么要换这个全局上下文,下面就来说明下

我们在使用数据库中经常会调用到Select ,而是用Select中就要使用游标,如果一个数据库的游标忘记关闭了,那么这个数据库的实例对象就会一直保留,跟线程.静态差不多的情况,无法释放

用了全局上下文就可以正常的释放了.

不过在这里还是说下..这个我在代码里真心没用,因为全部游标都是前面开后面关,当然也包括数据库

总的来说只要写数据库的代码时不是忘记关闭的用哪种都可以的,只是用全局上下文保险一点而已