-
用SparseArray / ArrayMap 代替HashMap
SparseArray:
如果key的类型已经确定为int类型,那么使用SparseArray,因为它避免了自动装箱的过程,如果key为long类型,它还提供了一个
LongSparseArray
来确保key为long类型时的使用,如果key类型为其它的类型,则使用ArrayMap
ArrayMap:
android.util.ArrayMap存储结构是由int[] mHashes和Object[] mArray两个数据组成,mHashes保存key的hashCode,mArray以键值对形式保存key和value。 ArrayMap取数据时通过二分法查找index,获取相应value。 ArrayMap在remove和clear后,会重新收缩数据,节约空间,但会降低执行效率。ArrayMap是牺牲了时间换取空间。根据官方描述,由于查找方式采用的是二分法,并且当你删除或者添加数据时,会对空间重新调整,ArrayMap不太适合数据量比较大的场景。
-
Enum (枚举)
避免使用枚举,用静态变量代替,枚举占用的内容大的多
-
减少 Bitmap 对象的内存占用
Bitmap是一个极容易消耗内存的大胖子,减小创建出来的Bitmap的内存占用是很重要的,通常来说有下面2个措施:
1.inSampleSize:缩放比例,在把图片载入内存之前,我们需要先计算出一个合适的缩放比例,避免不必要的大图载入。
2.decode format:解码格式,选择 ARGB_8888 / RBG_565/ ARGB_4444 / ALPHA_8,这几种格式存在很大差异和内存占用情况。
-
注意临时 Bitmap 对象的及时回收
我们会对 Bitmap 增加缓存机制,但是在某些时候,部分 Bitmap 是需要及时回收的。例如临时创建的某个相对比较大的 Bitmap 对象,在经过变换得到新的 Bitmap 对象之后,应该尽快回收原始的 Bitmap,这样能够更快释放原始 Bitmap 所占用的空间。
需要特别留意的是 Bitmap 类里面提供的createBitmap()
方法:
这个函数返回的 Bitmap 有可能和 source bitmap 是同一个,在回收的时候,需要特别检查 source bitmap 与 return bitmap 的引用是否相同,只有在不等的情况下,才能够执行 source bitmap 的 recycle() 方法
-
尽量地采用 int 类型
Android 系统中 float 类型的数据存取速度是 int 类型的一半,尽量优先采用 int 类型。而同样能作为整数的代名词,采用 int 替换 Integer 会让你的内存开销更小。
- 适当使用intern
JDK7以及以后String类提供了
intern()
方法,手动调用可以把对象放到常量池中,后续调用的时候如果在常量池中匹配到了就直接使用,避免重复创建对象,但是使用了intern()
之后会相当于花费多一点点时间,但是数据多的情况下,花费的那点时间和节省下来的空间来说还是不值一提的
-
尽量使用原字符串的 subString
当从已经存在的数据集中抽取出 String 的时候,尝试返回原数据的
subString
对象,而不要创建一个重复的对象。这一点比较少见,因为每次调用subString
方法都会创建一个新的String对象
-
避免在频繁调用的方法比如 onDraw() 里面执行对象的创建
类似 onDraw() 等频繁调用的方法,一定需要注意避免在这里做创建对象的操作,因为他会迅速增加内存的使用,而且很容易引起频繁的 gc,甚至是内存抖动。
-
循环里操作字符串的时候改用
StringBuffer
/StringBuilder
来操作
如果直接在循环里用
+
拼接字符串,会创建很多无用的对象,比如说以下代码在每次循环的时候都会创建了新的StringBuilder
对象,所以这种情况可以在外部创建一个StringBuilder
对象,在循环内调用append
方法
for(int i = 0; i < 100; i++) {
s += "a";
}