App内存优化整理

1.Android内存的管理方式

Android系统内存分配和回收方式

    一个app通常就是一个进程对应一个虚拟机,使用adb shell --> ps可以查看所有进程信息,具体内存相关信息可以使

dumpsys meminfo packagename查看,如下:

generic_x86:/ $ dumpsys meminfo xxx
Applications Memory Usage (in Kilobytes):
Uptime: 334565 Realtime: 334565


** MEMINFO in pid 2898 [xxx] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     8173     8124        0        0    25088    22685     2402
  Dalvik Heap    10553    10444        0        0    11928     7832     4096
 Dalvik Other     1329     1328        0        0
        Stack      424      424        0        0
       Ashmem        4        4        0        0
    Other dev        4        0        4        0
     .so mmap     1783      128      360        0
    .apk mmap      282        0       12        0
    .ttf mmap       79        0       44        0
    .dex mmap    10976      180    10796        0
    .oat mmap     2523        0      592        0
    .art mmap     1795     1476        0        0
   Other mmap     2191        4     1956        0
      Unknown      806      800        0        0
        TOTAL    40922    22912    13764        0    37016    30517     6498


 App Summary
                       Pss(KB)
                        ------
           Java Heap:    11920
         Native Heap:     8124
                Code:    12112
               Stack:      424
            Graphics:        0
       Private Other:     4096
              System:     4246


               TOTAL:    40922       TOTAL SWAP PSS:        0


 Objects
               Views:      325         ViewRootImpl:        1
         AppContexts:        2           Activities:        1
              Assets:        2        AssetManagers:        2
       Local Binders:        9        Proxy Binders:       15
       Parcel memory:        4         Parcel count:       18
    Death Recipients:        0      OpenSSL Sockets:        2
            WebViews:        0


 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0
并且GC在HEAP剩余空间不够时才发出垃圾回收动作;GC触发时,所有其他线程是被暂停的。

APP内存限制机制

    每个app分配都有最大内存限制,随着不同设备而不同。android系统是多任务系统,允许多应用同时运行,我们

不能让一个app吃掉设备所有内存,其他app没有内存占用而无法同时运行;如下:

public static void calculate(Context context){
        StringBuilder sb = new StringBuilder();
        ActivityManager atm = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
		//app运行手机对app的内存最大限制。
        int memClass = atm.getMemoryClass();
		//原则上LargememClass是在androidmanifest里设置了 largeheap=true后,能获得更大的上限,不过大部分手机这个值和memClass是一样的。
		//小米4手机 memClass:128 largememClass:512
        int largememClass = atm.getLargeMemoryClass();
        sb.append("memClass:" + memClass +"\n");
        sb.append("largememClass:" + largememClass +"\n");
		
		//freeMemory(),totalMemory(),maxMemory()反映的都是java这个进程的内存情况,跟操作系统的内存根本没有关系。
		//totalMemory()java虚拟机这个进程当时所占用的内存,从操作系统那里挖过来用上的内存
        Float totalMemory = Runtime.getRuntime().totalMemory() * 1.0f / (1024*1024);
		//freeMemory() java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存
        Float freeMemory = Runtime.getRuntime().freeMemory() * 1.0f / (1024*1024);
		//maxMemory()java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存,小米4手机maxMemory:128.0
        Float maxMemory = Runtime.getRuntime().maxMemory() * 1.0f / (1024*1024);
        sb.append("totalMemory:" + totalMemory +"\n");
        sb.append("freeMemory:" + freeMemory +"\n");
        sb.append("maxMemory:" + maxMemory +"\n");

        Log.e("MemoryUtils.calculate",sb.toString());
    }

切换应用时后台App清理机制

    app清理回收算法是LRU,当系统清理app的时候,会调用onTrimMemery。

监控内存的几种方式

    1.device monitor里内存走势图查看memory整体占用情况;
    2.通过device monitor 操作heap-->Cause GC可以看到一些信息,如下图:

    3.hprof文件对比查看内存泄漏,查看的是某一时刻Java堆中对象的变化。主要比较某一对象,在2个文件中的数量大

小,内存占用大小变化

    4.traceview进行内存泄漏的查看,查看的是内存中的函数调用变化。一类是调用次数不多,但每次调用却需要花费

长时间的函数。一类是那些自身占用时间不长,但调用却非常频繁的函数。

2.App内存优化方法

数据结构优化

    频繁字符串拼接使用stringbuilder,它比+拼接高效;大数据量存储使用ArrayMap,SparseArray替代HaspMap;避

存抖动,避免大量分配了一些局部变量。

对象复用

    复用系统自带的资源,例如adapter中的ContentView;避免在onDraw里创建对象;对象池设计的应用。

避免内存泄漏

    内存泄漏导致剩余可用heap堆越来越少,频繁出发GC。

    内存泄漏的例子:查询数据库而没有关闭Cursor;调用registerReceiver后未调用unregisterReceiver();未关闭

InputStream/OutputStream;Bitmap使用后未调用recycle();Context泄露,Activity在销毁后,由于被静态变量引用,

存不会被释放,或者被未运行完的线程引用也不会释放。

3.避免oom

避免方法

    主要是对占用内存大的资源---bitmap的避免:

    即使回收bitmap;

    避免bitmap浪费空间;

    try catch提示用户内存使用太大;

    对bitmap进行处理;

    做bitmap cache管理时,软引用bitmap,可以在系统内存不够时会释放软引用的对象。

处理bitmap方法

    例如一个jpg图片文件大小~11M,实际加载到bitmap~22M。

    尺寸:按比例取样图片BitmapFactory.Options.inSampleSize;如下:

	public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {
		// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(res, resId, options);
		// 调用上面定义的方法计算inSampleSize值
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
		// 使用获取到的inSampleSize值再次解析图片
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeResource(res, resId, options);
	}
    RGB色彩储存模式:

	public static final Bitmap.Config ALPHA_8
	public static final Bitmap.Config ARGB_4444
	public static final Bitmap.Config ARGB_8888
	public static final Bitmap.Config RGB_565

参考文档

慕课网上app内存优化的相关视频。
http://blog.csdn.net/wgw335363240/article/details/8878644
http://www.cnblogs.com/sunzn/p/3192231.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值