在前面一篇博客整理了Android性能优化之内存优化,这篇就整理整理内存优化方面的知识
RAM(random access memory)随机存取存储器。分为下面5种
###1.概念:
java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个)。这个可以和线程池相似。其实说白了常量池也是一个内存空间。但是和new创建出来的空间不一样。下面通过代码演示两者的区别
###2.代码演示
public static void main(String[] args) {
Integer a1 = new Integer(127) ;
Integer a2 = new Integer(127) ;
System.out.println(a1==a2); //false
Integer a3 = Integer.valueOf(127) ;
Integer a4 = Integer.valueOf(127) ;
System.out.println(a3 == a4); //true
System.out.println(a1 == a3 ); //false
Integer a5 = Integer.valueOf(128) ;
Integer a6 = Integer.valueOf(128) ;
System.out.println(a5 == a6); //false
}
由上述的代码可知:每次new的都是一个新的空间,而第二个方式为什么返回true呢?这是因为大部分的基本数据类型都实现了常量池技术。这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种double、float则没有实现。而且 Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,另外注意一点:String也实现了线程线程池技术。
下面就Integer型的为什么127可以而128不可以,看源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
那low和high是什么呢?
static final int low = -128;
static final int high;
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
看了上面的源码是不是明白了如果不是在-128到127之间,则会重新new的。
int a = 1;
int b = 1 ;
分析:
编译器先处理int a = 1;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向1。接着处理int b =1;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向1。这样,就出现了a与b同时均指向3的情况。这时,如果再让a=2;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并让a指向1;如果已经有了,则直接将a指向这个地址。
oom(Out Of Memory)在我们写代码的时候肯定经常遇到,那么为什么会出现这种问题呢?
图片是最容易造成oom的,尤其是在ListView中或者瀑布流中上下滑动,不断加载,程序很容易崩溃。
使用BitmapFactory.Options设置inSampleSize, 这样做可以减少对系统资源的要求。比如
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true ;
options.inSampleSize = 3 ;
上面2行代码就设置缩略图为原来的图的1/9。
图片像素:
图片默认是ARGB_8888,由此可以看出占用的内存比较大,再对图片要求不高的话,我们可以使用ARGB_4444或者RGB_565。
回收:
在我们不需要用某张图片的时候,可以将其回收
// 先判断是否已经回收
if(bitmap != null && !bitmap.isRecycled()){
// 回收并且置为null
bitmap.recycle();
bitmap = null;
}
4中引用类型
不过现在已经不推荐用软(弱)应用了,推荐使用LruCache(最近最少使用),关于4种种引用的具体用法会在下篇和LruCache一起介绍。
private static Context context ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
context = this ;
}
上面会导致Activity无法销毁,因为静态变量引用了当前Activity。
属性动画中有一类无限循环的动画,如果没有在onDestory()方法停止,就会无限循环下去,并且Activity的view将会被动画持有。而view又持有了Activity,导致Activity无法销毁。
OK,这篇关于内存优化的就结束了。