什么是内存溢出?

内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。

内存溢出的原因

1、内存中加载的数据太大
2、集合类中有对对象的引用,使用后未清空
3、代码中存在死循环或循环产生过多重复的对象实体;
4、使用的第三方软件中的BUG;
5、启动参数内存值设定的过小;

解决的办法

1,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
2,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
3,对代码进行走查和分析,找出可能发生内存溢出的位置。
 

什么是内存泄漏?

内存泄漏,即部分对象虽然已经不再使用,但是因为有root持有引用,所以并没有被销毁,所占用的内存一直没有被释放。一次两次发生影响不大。如果频繁发生,那么可用内存会渐渐不足,最终在某一次请求内存时发现内存不足而发生oom。这里要明确一个概念,只有强引用会发生内存泄漏,而weak等引用因为其特殊机制,所以影响不大。

怎么解决泄漏

内存泄漏是因为持有了activity引用导致无法被销毁,那么只有两个选择:及时取消引用,或者让这个引用多待一会,但是该gc回收的时候就销毁。

 

检测内存泄漏工具

因为内存泄漏是在堆内存中,所以对我们来说并不是可见的。通常我们可以借助MAT、LeakCanary等工具来检测应用程序是否存在内存泄漏。

1、MAT是一款强大的内存分析工具,功能繁多而复杂。

2、LeakCanary则是由Square开源的一款轻量级的第三方内存泄漏检测工具,当检测到程序中产生内存泄漏时,它将以最直观的方式告诉我们哪里产生了内存泄漏和导致谁泄漏了而不能被回收。

LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具
原理:监视一个即将被销毁的对象
白话:对被监控对象创建一个弱引用对象,后台线程检查这个对象是否被清除,如果没有就触发垃圾回收,垃圾回收之后如果这个弱引用对象还存在,说明发生了内存泄漏
1.RefWatcher.watch()函数会为被监控的对象创建一个KeyedWeakReference弱引用对象,是WeakReference对的子类,增加了键值对信息,后面会根据指定的键key找到弱引用对象;
2.在后台线程AndroidWatchExecutor中,检查KeyedWeakReference弱引用是否已经被清除。如果还存在,则触发一次垃圾回收之后。垃圾回收之后,如果弱引用对象依然存在,说明发生了内存泄露

Java得八大基本数据类型和占用字节数

byte  1字节  8位

short 2字节  16位

int   4字节  32位

long  8字节  64位

float  4字节 32位

double 8字节 64位

char  2字节 16位

boolean 1字节 8位