这里做一个笔记,希望可以在工作中帮助自己和他人。水平较水,可能笔记中主见较少,多为记录。
一,因为Android手机的内存大小限制,所以Android应用不能无限制的使用内存和cpu资源。
过多的使用内存资源会导致程序内存溢出,即OOM(out of memory)。
过多的使用cpu资源,一般是指做大量的耗时任务,会导致应用卡顿甚至无响应(ANR,application not response)。
内存泄露问题:当内存有一块空间我们认为已经不再使用了,应该会被GC回收时,因为他的引用一直在别处被持有着,这种情况下GC就会无法回收这块空间,从而导致应用占用的一些内存无法及时释放,内存泄露过多将提高OOM发生的几率
二,不同的手机对app运行时的内存限制是不一样的,google原生手机系统好像是默认分配16M。用代码测试我自己的手机(联想手机)时发现给的默认分配是192M,最大可分配512M。上代码:
Java
StringBuilder strBuilder = new StringBuilder();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
int memoClass = activityManager.getMemoryClass();//以M为单位
int largememoClass = activityManager.getLargeMemoryClass();//以M为单位
strBuilder.append("memoClass:" + memoClass + "\n");
strBuilder.append("largememoClass:" + largememoClass + "\n");
Float totalMemery = Runtime.getRuntime().totalMemory() * 1.0f / (1024 * 1024);
Float freeMemery = Runtime.getRuntime().freeMemory() * 1.0f / (1024 * 1024);
Float maxMemery = Runtime.getRuntime().maxMemory() * 1.0f / (1024 * 1024);
strBuilder.append("totalMemery:" + totalMemery + "\n");
strBuilder.append("freeMemery:" + freeMemery + "\n");
strBuilder.append("maxMemery:" + maxMemery + "\n");
tvMemoryInfo.setText(strBuilder.toString());
运行结果:
Android中吃内存的大户是图片加载。
三,监控内存的几种方法
1,使用代码获取并打印。
2,使用AS中的Monitor来监控。
四,app性能优化的方法
1,布局优化
尽量减少布局文件的层级,层级减少了,就意味着Android绘制时的工作量减少了,那么程序的性能就自然提高了。具体措施有:
- 删除布局中无用的控件和层级
- 多使用
<include>,<merge>,<viewstub>
标签
<include>
主要用于布局重用
<merge>
一般和<include>
配合使用,以减少布局的层级
<viewstub>
则提供了按需加载的功能,在需要的时候才会将viewstub中的布局加载到内存,提高了程序的初始化效率。(这个我在公司的项目中感觉好像从来没有用过)
2,数据结构优化
- 有的时候我们在程序运行中可能会在短时间内产生很多内存块,比如说将大量的字符串进行拼接操作,如果我们使用String这种结构进行拼接时,会产生大量的中间字符串内存块,这些是没有用的,gc在回收时就会使应用效率降低,如果是使用StringBuilder这种结构就不会有这种情况。
- 尽量使用ArrayMap,SparseArray来替换HashMap。内存使用更少,并且在数据量较多时,前两个效率更高,使用起来和HashMap的调用方法是一致的。
3,对象复用
比如说ListView/GridView里面ConvertView的复用。以及避免在onDraw()中执行对对象的创建。
4,避免内存泄露
内存泄露会导致剩余可用的内存越来越少,频繁触发gc。
Activity很容易泄露。比如在一个Activity中有一个耗时线程,当我们频繁的打开关闭这个Activity时,因为有耗时线程,所以在我们关闭这个Activity时它不会被立即回收,从而导致泄露。
5,强引用和软引用
当一个变量是成员变量并且没有指定他的类型是SoftReference时,那么它就是一个强引用,它的生命周期和所在类一致,在它的生命周期里它所占用的内存空间是不会被回收的。
当一个变量是成员变量并且类型为SoftReference<T>
时,它就是一个软引用,在它生命周期里当内存空间不足时是可以被回收的。这一点我们可以用来做内存优化,用以解决一些临时对象特别是临时的Bitmap对象的回收
强引用和软引用在图片加载中使用的比较多,到我们在加载一张图片时,当我们不再需要这个图片时,因为强引用在生命周期中是不会被回收的,所以使用软引用比较好。
在开发中我们使用到的第三方的图片加载框架中内部实现应该都是软引用+LRU(least resently used)算法实现的。