简单内存溢出分析

一: 程序计数器也叫线程私有区域、这是唯一不会发生OutOfMemoryError的区域 每个内核都只接受一条线程的指令、当线程执行完后 程序计数器也随机恢复、所以每个线程都需要 一个独立的计数器、独立存储 互相依赖。

二: 虚拟机栈也是线程私有、生命周期和线程的一样 每个方法被调用执行的时候都会创建一个Stack Frame(栈), 栈里储存这局部变量列表 方法出口 动态链接等、方法的调用执行过程对应这栈在虚拟机中的进出、局部变量列表储存这基本数据类型和String引用 对象引用地址、当栈无法扩展到足够的内存时候出报出OutOfMemoryError错

三:本地方法栈和虚拟机栈的功能类似 区别在于虚拟机栈执行的字节码文件 本地方法栈执行的Java Native 规范中并没有规定本地方法栈的数据结构等等、它也和虚拟机栈一样 抛出OutOfMemryError和StackOverflowError错位

四:java堆 内存中最大的一块被线程共享 、堆在虚拟机启动的时候创建 几乎所以的对象都在这里分配内存 堆既可以是固定大小也可以通过- Xmx 和 -Xms来扩展 如果在堆中没有完成实例分配而堆也无法扩展的时候会抛出OutOfMemoryError异常
简单内存溢出分析_第1张图片
简单内存溢出分析_第2张图片

五:方法区和堆一样是被线程共享的区域、储存已经被jvm加载后的类信息 常量 静态变量等等 ,它不是固定大小的 也可以扩展 也可以选择GC回收。方法区内存无法满足分配的时候会抛出*OutOfMemoryError异常

六:运行时常量 方法区的一部分 储存了字段 接口 方法 常量池(储存编译期的字面量和符号引用)、不过在方法区内自然受方法区的影响 当无法扩展的时候抛出OutOfMemoryError异常

简单内存溢出分析_第3张图片

七:内存、内存不属于虚拟机 但是会被频繁的引用 、在JDK1.4中加入了NIO类可以似的本地方法库直接分部堆外内存 、然后在通过在方法区中的DirectByteBuffer对象进行引用、当内存不够动态扩展的时候引发OutOfMemoryError异常

开发注意点:

一 巨图加载:
1.根据需要显示图片控件的大小对图片进行压缩显示
2.如果图片数量非常多,则使用LruCache等缓存机制,将所有图片占据的内容维持在一个范围内。
3.加载单个图片非常巨大,并且不允许压缩。比如:世界地图,清明上河图等等 使用
BitmapRegionDecoder
二 内存优化
1.优化RAM,即降低运行时内存。这里的目的是防止程序发生OOM异常,以及降低程序由于内存过大被LMK机制杀死的概率。另一方面,不合理的内存使用会使GC大大增多,从而导致程序变卡。
2.优化ROM,即降低程序占ROM的体积。这里主要是为了降低程序占用的空间,防止由于ROM空间不足导致程序无法安装。
三 内存检测和修改
内存泄露:简单来说对象由于编码错误或系统原因,仍然存在着对其直接或间接的引用,导致系统无法进行回收。内存泄露,容易留下逻辑隐患,同时增加了应用内存峰值与发生OOM的概率。它属于bug issue,是我们一定要修改的。
Square的开源库leakcanry是一个非常不错的选择,它通过弱引用方式侦查Activity或对象的生命周期,若发现内存泄露自动dump Hprof文件,通过HAHA库得到泄露的最短路径,最后通过notification展示。
四 降低运行时内存的一些方法
Android 2.x系统,当dalvik allocated + external allocated + 新分配的大小 >= dalvik heap 最大值时候就会发生OOM。其中bitmap是放于external中
Android 4.x系统,废除了external的计数器,类似bitmap的分配改到dalvik的java heap中申请,只要allocated + 新分配的内存 >= dalvik heap 最大值的时候就会发生OOM(art运行环境的统计规则还是和dalvik保持一致)

1.减少bitmap占用的内存
Android 2.x 系统 BitmapFactory.Options 里面隐藏的的inNativeAlloc反射打开后,申请的bitmap就不会算在external中。对于Android 4.x系统,可采用facebook的fresco库,即可把图片资源放于native中。

2.图片按需加载
即图片的大小不应该超过view的大小。在把图片载入内存之前,我们需要先计算出一个合适的inSampleSize缩放比例,避免不必要的大图载入。对此,我们可以重载drawable与ImageView,例如在Activity ondestroy时,检测图片大小与View的大小,若超过,可以上报或提示。

3.统一的bitmap加载器
Picasso、Fresco都是比较出名的加载库,同样微信也有自己的库ImageLoader。加载库的好处在于将版本差异、大小处理对使用者不感知。有了统一的bitmap加载器,我们可以在加载bitmap时,若发生OOM(try catch方式),可以通过清除cache,降低bitmap format(ARGB8888/RBG565/ARGB4444/ALPHA8)等方式,重新尝试。

4.图片存在像素浪费
对于.9图,美工可能在出图时在拉伸与非拉伸区域都有大量的像素重复。通过获取图片的像素ARGB值,计算连续相同的像素区域,自定义算法判定这些区域是否可以缩放。关键也是需要将这些工作做到系统化,可及时发现问题,解决问题。

你可能感兴趣的:(线程,虚拟机,局部变量,内存溢出)