http://blog.csdn.net/fastthinking/article/details/38898193
1.安卓开发时,如何开发出质量高的代码?如何及时释放内存,不造成内存泄露?
公共变量不要包含对Activity/Fragment的引用。保证及时的销毁Activity/Fragment的对象。
参考http://blog.csdn.net/a345017062/article/details/8301398(Activity、Fragment对象内存泄漏的解决思路)
activity contex and memery leak
http://blog.csdn.net/prog_dong/article/details/5618995
2.此人遇到的问题应该是内存管理不当。fragment虽然调用了remove。但是其中的变量可能生命周期大于fragment并且引用了fragment。导致无法回收。
3.如何判断程序是否存在内存泄露?
http://www.360doc.com/content/14/0516/14/9462341_378228520.shtml
4.content、Application、SharePreference与全局变量如何使用?
http://www.360doc.com/content/12/0531/11/7559693_214938173.shtml
5.android静态引用变量的生命周期
http://blog.csdn.net/ctcwri/article/details/8858414
//
http://blog.csdn.net/ctcwri/article/details/8858414
Android是用Java开发,其静态变量的生命周期遵守Java的设计。我们知道静态变量是在类被load的时候分配内存的,并且存在于方法区。当类被卸载的时候,静态变量被销毁。在PC机的客户端程序中,一个类被加载和卸载,可简单的等同于jvm进程的启动和结束。那么在Android中呢?用的Dalvik vm也是一样的。不过Android不太突出的进程概念,所以对静态变量的生命周期就会感觉模糊,这种模糊对于值类型是无所谓的,如果是静态的对象引用,则与内存回收、内存泄漏这些问题有关,有必要加深研究和理解。
一、静态变量在类被加载的时候分配内存。
类在什么时候被加载?
当我们启动一个app的时候,系统会创建一个进程,此进程会加载一个Dalvik VM的实例,然后代码就运行在DVM之上,类的加载和卸载,垃圾回收等事情都由DVM负责。也就是说在进程启动的时候,类被加载,静态变量被分配内存。
二、静态变量在类被卸载的时候销毁。
类在什么时候被卸载?
在进程结束的时候。
说明:一般情况下,所有的类都是默认的ClassLoader加载的,只要ClassLoader存在,类就不会被卸载,而默认的ClassLoader生命周期是与进程一致的,本文讨论一般情况。
三、Android中的进程什么时候结束
这个是Android对进程和内存管理不同于PC的核心——如果资源足够,Android不会杀掉任何进程,另一个意思就是进程随时可能会被杀掉。而Android会在资源够的时候,重启被杀掉的进程。也就是说静态变量的值,如果不做处理,是不可靠的,可以说内存中的一切都不可靠。如果要可靠,还是得保存到Nand或SD卡中去,在重启的时候恢复回来。
另一种情况就是不能把退出所有Activity等同于进程的退出,所以在用户点击图标启动应用的时候,以前存放于静态变量中的值,有可能还存在,因此要视具体情况给予清空操作。
四、Application也是一样不可靠
Application其实是一个单例对象,也是放在内存中的,当进程被杀掉,就全清空了,只不过Android系统会帮重建Application,而我们存放在Application的数据自然就没有了,还是得自己处理。
五、静态引用的对象不会被垃圾回收
只要静态变量没有被销毁也没有置null,其对象一直被保持引用,也即引用计数不可能是0,因此不会被垃圾回收。因此,单例对象在运行时不会被回收。
// http://blog.csdn.net/u013233097/article/details/50313993
Android中内存泄露的原因分析:
有垃圾回收机制,为什么还会出现内存泄露:
了解GC回收的原理:
GC会选择一些它了解还存活的对象作为内存遍历的根节点(GC Roots),比方说thread stack中的变量,JNI中的全局变量,zygote中的对象(class loader加载)等,然后开始对heap进行遍历。到最后,部分没有直接或者间接引用到GC Roots的就是需要回收的垃圾,会被GC回收掉。
1,内存泄露和内存溢出:
内存泄露:
Java内存泄漏指的是进程中某些对象(垃圾对象)已经没有使用价值了,但是它们却可以直接或间接地引用到gc roots导致无法被GC回收。无用的对象占据着内存空间,使得实际可使用内存变小,形象地说法就是内存泄漏。
内存溢出:
内存溢出(out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。此时软件或游戏就运行不了,系统会提示内存溢出,有时候会自动关闭软件。
Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M。因此我们所能利用的内存空间是有限的。如果我们的内存占用超过了一定的水平就会出现OutOfMemory的错误。
为什么会出现内存不够用的情况呢?我想原因主要有两个:
- 由于我们程序的失误,长期保持某些资源(如Context)的引用,造成内存泄露,资源造成得不到释放。
- 保存了多个耗用内存过大的对象(如Bitmap),造成内存超出限制。
区别:
内存泄露memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存迟早会被占
光。 是指向系统中申请分配内存进行使用(new),但使用完后,却没有归还。申请到的内存自己也不能再访问,而系统也不能再次将它分配给需要的程序。
内存溢出out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给他存了long才能存下的数。
比如栈:栈满时,进行进栈,内存溢出。栈空时,进行出栈,内存也会溢出。分配内存不足以放下数据项序列,称为内存溢出。
内存泄露会导致内存溢出。
2,导致内存泄露的原因分析 :
1,静态变量导致的内存泄露:
2,单例模式导致的内存泄露:
调用上面的代码:
3,属性动画导致的内存泄露:
属性动画中有一类无线循环的动画,如果在Activity中播放此类动画而且没有在onDestory中去 停止动画。那么动画会一直播放下去,尽管已经看不到动画效果了。并且这个时候Activity的View会被动画持有。而View又持有了Activity无法释放。下面动画是无线循环,会泄露当前的Activity,解决办法是在Activity的onDestory中调用animator.cancel();
4.Bitmap使用不当造成内存泄露:
当我们使用Bitmap对象开辟对象时,较大的Bitmap对象会被创建,其占用内存过多,超出堆的上限时,便会抛出内存泄露的危险。Bitmap对象不在使用时调用recycle()释放内存时会造成内存泄露。如果一个Bitmap对象比较占内存,当它不在被使用的时候,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存,但这不是必须的,视情况而定。
第一、及时的销毁,解决方案。
虽然,系统能够确认Bitmap分配的内存最终会被销毁,但是由于它占用的内存过多,所以很可能会超过Java堆的限制。因此,在用完Bitmap时,要及时的recycle掉。recycle并不能确定立即就会将Bitmap释放掉,但是会给虚拟机一个暗示:“该图片可以释放了”。
5,handler造成的内存泄露:
handler:Handler持有对UI主线程消息队列MessageQueue和循环Looper的引用。子线程可以通过Handler将消息发送到UI线程的消息队列MessageQueue中。UI主线程通过Looper循环查询消息队列的UI_MQ,当发现有消息存在时会将消息从队列中取出。首先分析消息,通过消息的参数判断该消息对应的Handler,然后将消息分发到指定的Handler进行处理。