android开发进阶----how to省内存

1 bitmap回收

Bitmap对象在不使用时,我们应该先调用recycle(),然后才它设置为null.

虽然Bitmap在被回收时可以通过BitmapFinalizer来回收内存。但是调用recycle()是一个良好的习惯

在Android4.0之前,Bitmap的内存是分配在Native堆中,调用recycle()可以立即释放Native内存

从Android4.0开始,Bitmap的内存就是分配在dalvik堆中,即JAVA堆中的,调用recycle()并不能立即释放Native内存但是调用recycle()也是一个良好的习惯。


As of Android 3.0 (API level 11), the pixel data is stored on the Dalvik heap along with the associated bitmap.

Android 2.3.3 (API level 10) and lower, using recycle() is recommended,use recycle() only when you are sure that the bitmap is no longer being used. 

When an app is running on Android 3.0 or higher and a bitmap is evicted from the LruCache, a soft reference to the bitmap is placed in a HashSet, for possible reuse later with inBitmap

save bitmap for late use

if (Utils.hasHoneycomb()) {
    mReusableBitmaps =
            Collections.synchronizedSet(new HashSet<SoftReference<Bitmap>>());
}
mMemoryCache = new LruCache<String, BitmapDrawable>(mCacheParams.memCacheSize) {

    // Notify the removed entry that is no longer being cached.
    @Override
    protected void entryRemoved(boolean evicted, String key,
            BitmapDrawable oldValue, BitmapDrawable newValue) {
        if (RecyclingBitmapDrawable.class.isInstance(oldValue)) {
            // The removed entry is a recycling drawable, so notify it
            // that it has been removed from the memory cache.
            ((RecyclingBitmapDrawable) oldValue).setIsCached(false);
        } else {
            // The removed entry is a standard BitmapDrawable.
            if (Utils.hasHoneycomb()) {
                // We're running on Honeycomb or later, so add the bitmap
                // to a SoftReference set for possible use with inBitmap later.
                mReusableBitmaps.add
                        (new SoftReference<Bitmap>(oldValue.getBitmap()));
            }
        }
    }
....
}


OnLowMemory

OnLowMemory是Android提供的API,在系统内存不足,所有后台程序(优先级为background的进程,不是指后台运行的进程)都被杀死时,系统会调用OnLowMemory。系统提供的回调有:

  • Application.onLowMemory()

  • Activity.OnLowMemory()

  • Fragement.OnLowMemory()

  • Service.OnLowMemory()

  • ContentProvider.OnLowMemory()


onTrimMemory(int)

实现onTrimMemory(int)回调,当内存不够,dalvik可能会杀app来回收内存时,可以在这个回调里做点事情


To be notified when the user exits your UI, implement the onTrimMemory() callback in your Activity classes. You should use this method to listen for the TRIM_MEMORY_UI_HIDDEN level, which indicates your UI is now hidden from view and you should free resources that only your UI uses.This is distinct from the onStop() callback, which is called when an Activity instance becomes hidden, which occurs even when the user moves to another activity in your app. So although you should implement onStop() to release activity resources such as a network connection or to unregister broadcast receivers, you usually should not release your UI resources until you receive onTrimMemory(TRIM_MEMORY_UI_HIDDEN). This ensures that if the user navigates back from another activity in your app, your UI resources are still available to resume the activity quickly.

OnTrimMemory的参数是一个int数值,代表不同的内存状态:

  • TRIM_MEMORY_COMPLETE:内存不足,并且该进程在后台进程列表最后一个,马上就要被清理

  • TRIM_MEMORY_MODERATE:内存不足,并且该进程在后台进程列表的中部。

  • TRIM_MEMORY_BACKGROUND:内存不足,并且该进程是后台进程。

  • TRIM_MEMORY_UI_HIDDEN:内存不足,并且该进程的UI已经不可见了。      

以上4个是4.0增加

  • TRIM_MEMORY_RUNNING_CRITICAL:内存不足(后台进程不足3个),并且该进程优先级比较高,需要清理内存

  • TRIM_MEMORY_RUNNING_LOW:内存不足(后台进程不足5个),并且该进程优先级比较高,需要清理内存

  • TRIM_MEMORY_RUNNING_MODERATE:内存不足(后台进程超过5个),并且该进程优先级比较高,需要清理内存       

以上3个是4.1增加


You should respond by further releasing resources based on the following memory levels delivered by onTrimMemory():

  • TRIM_MEMORY_RUNNING_MODERATEYour app is running and not considered killable, but the device is running low on memory and the system is actively killing processes in the LRU cache.
  • TRIM_MEMORY_RUNNING_LOWYour app is running and not considered killable, but the device is running much lower on memory so you should release unused resources to improve system performance (which directly impacts your app's performance).
  • TRIM_MEMORY_RUNNING_CRITICALYour app is still running, but the system has already killed most of the processes in the LRU cache, so you should release all non-critical resources now. If the system cannot reclaim sufficient amounts of RAM, it will clear all of the LRU cache and begin killing processes that the system prefers to keep alive, such as those hosting a running service.


    when your app process is currently cached, you may receive one of the following levels fromonTrimMemory():
    • TRIM_MEMORY_BACKGROUNDThe system is running low on memory and your process is near the beginning of the LRU list. Although your app process is not at a high risk of being killed, the system may already be killing processes in the LRU cache. You should release resources that are easy to recover so your process will remain in the list and resume quickly when the user returns to your app.
    • TRIM_MEMORY_MODERATEThe system is running low on memory and your process is near the middle of the LRU list. If the system becomes further constrained for memory, there's a chance your process will be killed.
    • TRIM_MEMORY_COMPLETEThe system is running low on memory and your process is one of the first to be killed if the system does not recover memory now. You should release everything that's not critical to resuming your app state.
      the onTrimMemory() callback was added in API level 14, you can use the onLowMemory() callback as a fallback for older versions, which is roughly equivalent to the TRIM_MEMORY_COMPLETE event.

OnLowMemory和OnTrimMemory的比较

1,OnLowMemory被回调时,已经没有后台进程;而onTrimMemory被回调时,还有后台进程。
2,OnLowMemory是在最后一个后台进程被杀时调用,一般情况是low memory killer 杀进程后触发;而OnTrimMemory的触发更频繁,每次计算进程优先级时,只要满足条件,都会触发。
3,通过一键清理后,OnLowMemory不会被触发,而OnTrimMemory会被触发一次。


@Override
public void onTrimMemory(int level) {
    Log.e(TAG, " onTrimMemory ... level:" + level);     
}

@Override
public void onLowMemory() {     
    Log.e(TAG, " onLowMemory ... ");     
}


4 ActivityManager使用


private void displayBriefMemory() {
    final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(info);
    Log.i(TAG, "系统剩余内存:" + (info.availMem >> 10) + "k");
    Log.i(TAG, "系统是否处于低内存运行:" + info.lowMemory);
    Log.i(TAG, "当系统剩余内存低于" + (info.threshold >> 10) + "k" + "时就看成低内存运行");

    util.SavedToText(TAG, "meminfo  系统剩余内存:" + (info.availMem >> 10) + "k"
            + "  " + "系统是否处于低内存运行:" + info.lowMemory + "  " + "当系统剩余内存低于"
            + (info.threshold >> 10) + "k" + "时就看成低内存运行");
}


参考Best Performance

参考点击打开链接 Manage Your Apps

参考Performance Tips

参考Manage Bitmap Memory

参考点击打开链接

TO Be Continued...

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值