Android内存管理优化技巧

1.使用service的风险

当应用程序使用service执行后台操作时,一定要保证只用执行操作时才让service运行,操作完成时,service应当停止运行,为防止内存泄露,谷歌官方推荐使用IntentService。

2.当界面不可见的时候,释放内存

到用户打开另一个app时,上一个app已经处于不可见状态,我们应到把与界面有关的资源进行释放,只需要在Activity中,重写onTrimMemory()方法,然后在这个方法

中见监听TRIM_MEMORY_UI_HIDDEN这个级别,一旦触发之后可以进行一些操作:

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        if (level == TRIM_MEMORY_UI_HIDDEN){
            //TODO Somethings
        }
    }


3.当内存紧张时释放内存

onTrimMemory()方法[整个程序不可见时,触发]方法有很多回调类型的函数,我们可以根据回调中传入的API级别,去处理资源:

TRIM_MEMORY_BACKGROUND 表示程序正常运行,不会被杀掉,但内存有点低,系统可能已经根据LruCache规则去杀进程

TRIM_MEMORY_MODERATE 表示程序运行正常,内存已经很低了,我们应该释放一些不必要的内存,否则会影响程序性能

TRIM_MEMORY_RUNNING_CRITICAL 表示程序运行正常,但系统已经开始根据lruCache规则杀掉大部分缓存进程,我们应当去释放不必要的资源

4.避免在Bitmap上浪费内存

这个前面说过,不懂的可以去看看前面博客的Bitmap加载大图优化和LruCache和DiskLruCache双缓存机制

5.使用优化过的数据集合

Android API中提供了一些优化过的数据集合工具类:SparseArray、SparseBooleanArray、LongSparseArray。可以让程序更加高效

举个例子,普通hashMap以整型为key存放数据:

这里共存放个5组数据,以整型为键值:

HashMap<Integer,String> map = new HashMap<>();

map.put(1,"value");

map.put(2,"value");

map.put(3,"value");

map.put(4,"value");

map.put(5,"value");

上面的HashMap在内存中开辟的空间是这样的:可以看出它存放数据时,开辟了63个空间只用了5个,绝大部分都浪费掉了


会造成内存的浪费

接下来看一下优化过的SparseArray,可以看到,他是根据使用到的数据个数进行开辟空间一共只用18个,大大节省内存开支


优化过的集合

SparseArray<String>  //已将key作为整形

SparseArray<String>  array = new SparseArray<>();

array.put(1,"value");

array.put(2,"value");

array.put(3,"value");

array.put(4,"value");

array.put(5,"value");



6.了解内存的开支状况

1>使用枚举通常会比使用静态常量要消耗两倍以上内存

2>任何一个Java类,包括内部类、匿名类都要占用500字节的内存空间

3>任何一个类的实例都要消耗12-16字节的内存开支,频繁new对象也会影响性能

4>使用HashMap时,即使只设置了一个基本数据类型的键,e.g  int,但也会按照对象的大小来分配内存,大概是32字节,因此,像上面一样

5>多用优化过的数据集合

7.反抽象编程概念

面向对象的编程,会编写很多额外的代码,即使这些代码执行不到,也会映射到内存中,不仅占用更多的内存,在执行效率方面

会有所降低,所以不要滥用抽象编程

8.避免使用依赖注入框架

使用依赖注入框架后会在初始化的过程中,历经较长的初始化的过程,用不到的注解对象也会加载到内存中,可能很久

之后才会得到释放

9.使用ProGuard混淆代码

ProGuard除了混淆代码之外,还具有压缩优化代码的功能,可以删除一些无用的代码,并对类、字段、方法

重命名,重命名之后,变得更加简短,更加节省内存

Proguard的路径在SDK目录下的tools中-----------studiosdk/tools/proguard

然后修改app的build下的buildTypes的minifyEnabled值为true,就可以混淆代码

 
 
buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}



10.使用多个线程
想使用多个线程很简单,只需在AndroidManifest.xml文件中的应用程序组件
中声明一个android:process属性即可
比如:我想让遍历文件夹的一个Service可以运行在一个单独的线程中:

<Service android:name = "FolderService" android:process = ":background">
</Service>










猜你喜欢

转载自blog.csdn.net/Allan_Bst/article/details/72870789