初识内存泄露(一)

来源:互联网 发布:mac变色龙引导工具 编辑:程序博客网 时间:2024/06/17 03:33
何为内存泄露:内存不在GC控制之内。
当对象已经不需要使用了,本该被回收了,但却有另外一个正在使用的对象持有它的引用。导致对象不能被回收。这种导致了本该被回收的对象不能被回收而停留在堆内存中就产生了内存泄露

了解java垃圾回收机制:GC==》只有在捕捉到对象没有任何引用的时候才会进行回收
同时也不能频繁调用GC ,GC也是很耗性能的,频繁调用会出现内存抖动,就会导致进程、UI等卡顿
内存抖动:在短时间内,进行大量的对象创建和回收。所以频繁二字很关键。所以比如在for循环中 new 对象。循环次数小的话还好,若是循环次数大(n次引用,n次实例)。这样频繁的实例化对象和回收就不是很好,=改进=》做法可以在for循环外面声明对象变量,然后在for循环内部进行赋值(做到一次引用,n次实例),这样对象的生命周期变了,当方法执行完毕,才会被销毁回收。

内存分配几种策略
1:静态的
静态的存储区:内存在程序编译的时候就分配好的,这块内存在程序运行期间都一直存在。
主要存放:静态数据,全局的static数据和一些常量
2:栈式的:是一块连续的内存区域,大小由操作系统决定的
在执行函数方法时,函数一些内部变量的存储都可以放在栈上面创建,函数执行结束的时候这些存储单元就会自动被释放,栈内存包括分配的运算速度很快,内存内置在处理器里面,容量有限
3:堆式的:是不连续的内存区域,空间灵活,比较大
也叫动态内存分配,可以通过malloc或者new来申请分配一个内存。在c/c++可能需要自己负责释放(java则就依赖GC)在c/c++可以收到控制内存,需要很高的素养来解决内存问题。java在这一块就没有什么好的方法去解决内存问题
堆内存管理麻烦,因为频繁的new/remove会造成大量的内存碎片,随着时间的推移会慢慢导致效率低下
对于栈的话,先进后出,不会产生碎片,运行效率稳定
1:成员变量全部存储在堆中,(包括基本数据类型,引用和引用对象的实体)=》因为他们属于类,类对象最终还是要被new出来的
2:局部变量的基本数据类型和引用存储在栈内存中==》因为他们属于方法中,生命周期随方法执行完毕而结束
所以一般内存泄露讨论的是堆内存,
比如:像ListView GridView RecyclerView加载大量的数据和图片的时候
因为图片是非常占用内存的,如果没有处理好,很容易就会内存溢出
列表在反复滑动就要进行相关资源的回收==》如Listview重用ConvertView机制
就需要缓存机制==》就要使用一些特殊的java类、
算法:lrucache (最近最少使用先回收)
特殊java类:利用回收,StrongReference,SoftReference,WeakReferecnce,PhatomReference
名字回收机制 生命周期
强引用从不回收,对象的一般保存JVM停止的时候才会终止
软引用当内存不足的时候,使用SoftReference<String>结合ReferenceQueue构造有效期短内存不足的时候
弱引用在垃圾回收的时候: 使用同软引用,GC后终止
虚引用在垃圾回收的时候 使用:结合RecerenceQueue来跟踪对象垃圾回收活动,GC终止后