Android内存优化
内存优化是Android性能优化中最重要的环节之一,良好的内存管理可以提高应用的稳定性和用户体验。
面试题
1. 什么是内存泄漏?如何避免?
内存泄漏是指程序在申请内存后,无法释放已申请的内存空间,导致系统内存不断减少。
常见的内存泄漏场景:
// 1. 静态变量持有Activity引用
public class MainActivity extends Activity {
private static Context sContext; // 错误示例
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sContext = this; // 可能导致内存泄漏
}
}
// 2. 内部类持有外部类引用
public class MainActivity extends Activity {
private Handler mHandler = new Handler() { // 错误示例
@Override
public void handleMessage(Message msg) {
// 处理消息
}
};
}
// 正确的做法:使用静态内部类和弱引用
public class MainActivity extends Activity {
private static class MyHandler extends Handler {
private WeakReference<MainActivity> activityRef;
MyHandler(MainActivity activity) {
activityRef = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = activityRef.get();
if (activity != null) {
// 处理消息
}
}
}
}2. OOM(Out Of Memory)的原因和解决方案?
常见的OOM原因:
- 加载大图片
- 内存泄漏积累
- 内存抖动
- 数据结构不合理
解决方案:
// 1. 图片优化
public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
// 2. 使用LruCache缓存
private LruCache<String, Bitmap> mMemoryCache;
public void initCache() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
}3. 什么是内存抖动?如何解决?
内存抖动是指程序在短时间内频繁地创建和销毁对象,导致内存波动剧烈。
示例和解决方案:
// 错误示例:在onDraw中创建对象
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint(); // 每次绘制都创建对象
// 绘制操作
}
// 正确示例:
private Paint mPaint; // 类成员变量
public void init() {
mPaint = new Paint(); // 初始化时创建
}
@Override
protected void onDraw(Canvas canvas) {
// 使用已创建的对象
// 绘制操作
}4. Android中的内存管理机制是什么?
主要包括以下几个方面:
-
分配机制
- 应用程序内存限制
- 堆内存和栈内存
-
回收机制
- GC(垃圾回收)
- 弱引用和软引用
-
监控方式
// 获取内存信息
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(memoryInfo);
// 打印内存信息
Log.d("Memory", "系统剩余内存:" + memoryInfo.availMem / 1024 / 1024 + "MB");
Log.d("Memory", "系统是否处于低内存运行:" + memoryInfo.lowMemory);5. 如何优化Bitmap内存占用?
主要优化方向:
- 图片压缩
- 内存缓存
- 及时回收
示例代码:
// 1. 图片压缩
public static Bitmap compressBitmap(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
byte[] bytes = baos.toByteArray();
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
// 2. 使用Glide加载图片
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
// 3. 及时回收
public void recycleBitmap() {
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
}
}优化建议
- 使用内存检测工具
- 建立内存泄漏预警机制
- 制定内存优化规范
- 进行线上监控
- 定期进行代码Review