1. 什么是内存泄漏和内存溢出java
内存泄漏:能够简单地理解为内存丢了,也就是说new以后忘记释放掉了,致使内存一直在被占用,程序没法再使用这个内存单元,直到程序结束才能使用。这就是内存泄漏了。数据库
内存溢出:溢出就是装不下,漫了出来,好比为一个变量开辟了一个int类型的空间,却要把一个long型或float型的数据存进去,这个就是溢出。数组
屡次或者大量的内存泄漏最终会致使内存溢出,从而致使OOM(out of memory)。架构
2. java中的内存架构工具
图片来源(https://my.oschina.net/xiaohui249/blog/170013)ui
下图是JVM的结构示意图,每当启动一个java程序时,就会相应地建立一个虚拟机实例。this
(1) Garbage Collection:java的垃圾回收机制,主要就是负责回收堆中的对象(该对象再也不被引用)。spa
(2) Classloader Sub-System:java中的类加载系统,每个class类只会被加载器加载一次,加载主要有两种方式(懒汉:须要的时候才加载,饿汉:首先加载完成)。加载器主要用来定位和导入二进制class文件。操作系统
(3) Execution Engine:JVM中的执行引擎,主要就是负责执行包含在加载器中方法的指令。JNI以及Native Library的存在是为了弥补java的缺陷,java在运行速度上比C++慢许多,并且没法访问操做系统底层,因此native和JNI就至关与java和C之间的接口,是为了使用C的一些程序而存在的。.net
(4) Java Memory Allocation Area:java的虚拟机内存,也就是执行时的数据区。
java的虚拟机内存又主要分为几个部分
(1) 堆(Heap):存放new建立的对象和数组,java的gc机制也主要是对这部分来进行操做的。JVM只有一个堆供全部的线程来共享
(2) 栈(Stack):java中的栈用来存放基本的数据类型以及对象的引用。JVM为每个新的线程分配一个栈
(3) 方法区(Method Area):方法区包含全部的class变量以及static变量。方法区又叫作静态区,跟堆有些相似,是被全部的线程共享的。
(4) 程序计数器(Program Count Register):程序计数器。每次有一个新线程被建立时,都会获得一个PC寄存器(程序计数器)
(5) 本地方法栈(Native Stack):每一个线程运行时本身的本地方法栈
图片来源(https://my.oschina.net/xiaohui249/blog/170013)
3. 为何会产生内存泄漏哪?
java 中的堆栈是如何工做的哪
栈:当每次有新的方法运行时,就会在栈中加一个frame,也就是一个内存单元,保存该方法调用的参数,局部变量以及返回地址,而在方法结束后,对应的frame会被从栈中移除,局部变量占用的空间也会被释放。也就是说栈会本身对内存进行清理和释放。
堆:java中new的对象都会存储在堆中,当这些对象没有再被引用时,就会等待被GC回收。若是咱们建立了大量的对象,而又一直被引用,就会致使这些对象一直没法释放,从而形成内存泄漏。java中的引用又分为强,软,弱,虚四种引用。而真正形成内存泄漏的实际上是强引用,由于GC不会回收一个强引用的对象。
4. Android中可能形成内存泄漏的情景,也就是强引用持有的状况
(1) 全局进程的static变量
(2) Activity以外的一些线程,没有清空对Activity的强引用
5. Android中可能致使内存泄漏的具体状况
(1) static activity:在类中定义了静态的activity变量,而在activity生命周期结束后又没有清空
(2) static views:相似于上述的状况
(3) Inner Classes:内部类虽然能够提升代码的可读性以及封装性,可是若是一个内部类持有了静态变量的引用,并且忘记了销毁的时候变为null,就会致使内存泄漏
(4) Anonymous Classes:相似与Inner Classes
(5) handler:在没有执行完handler message时,activity被销毁了。或者handler使用完后并无释放掉对象
(6) Threads
(7) TimerTask
(8) Sensor Manager
(9) SQL:数据库查询时忘了关闭掉游标Cursor,虽然可能每次查询数据量都不是很大,可是长时间的大量操做的状况下是可能出现内存泄漏的
(10) Bitmap:程序中可能使用了太多本身建立的Bitmap,而忘记释放掉,最多见的是Gallery以及ListView这种列表
6. Android中具体的内存泄漏分析和定位
检测内存泄漏有一些经常使用的工具,好比MAT工具,AndroidStudio中自带的分析工具,以及leakCanary,这些工具的使用后期打算专门写文章介绍。
在Acitivity的生命周期中,在某些方法例如onPause(), onStop(), onDestory()方法中尽可能地释放一些资源
尽可能使用getApplicationContext(),而避免使用create(this)