3.3 KiB
3.3 KiB
内存管理
目录
Android内存管理
内存模型
// Android 内存模型:
// 1. Java 堆:对象实例
// 2. Native 堆:Native 代码分配
// 3. 栈:方法调用、局部变量
// 4. 方法区:类信息、常量
内存限制
// 不同设备有不同的内存限制
// 低端设备:16MB、32MB
// 中端设备:64MB、128MB
// 高端设备:256MB、512MB+
// 获取内存限制
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int maxMemory = am.getMemoryClass(); // MB
内存分配
堆内存分配
// Java 对象分配在堆上
String str = new String("Hello"); // 分配在堆上
// 大对象可能直接分配在老年代
byte[] largeArray = new byte[10 * 1024 * 1024]; // 10MB
栈内存分配
// 局部变量分配在栈上
public void method() {
int localVar = 10; // 分配在栈上
String str = "Hello"; // 引用在栈上,对象在堆上
}
垃圾回收
GC 类型
// 1. Minor GC:新生代回收
// 2. Major GC:老年代回收
// 3. Full GC:整个堆回收
GC 算法
// ART 使用多种 GC 算法:
// 1. 标记-清除
// 2. 标记-复制
// 3. 标记-整理
// 4. 分代收集
GC 触发时机
// 1. 堆内存不足
// 2. 手动调用 System.gc()
// 3. 对象分配失败
内存泄漏
常见泄漏场景
// 1. 静态变量持有 Context
private static Context sContext; // ❌
// 2. Handler 内存泄漏
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// Handler 持有 Activity 引用
}
}; // ❌
// 3. 监听器未注销
sensorManager.registerListener(this, sensor, ...);
// 忘记注销 // ❌
// 4. 内部类持有外部类引用
public class Outer {
class Inner {
// Inner 持有 Outer 引用
}
}
检测工具
// 1. LeakCanary:自动检测内存泄漏
dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
}
// 2. Memory Profiler:Android Studio 工具
// 3. MAT:Memory Analyzer Tool
内存优化
优化方法
// 1. 避免内存泄漏
// - 使用弱引用
// - 及时释放资源
// - 使用 Application Context
// 2. 图片优化
// - 压缩图片
// - 使用合适格式
// - 及时回收 Bitmap
// 3. 对象池
// - 复用对象
// - 减少创建开销
// 4. 数据结构优化
// - 使用合适的数据结构
// - 避免不必要的对象创建
面试常见问题
Q1: Android 内存管理机制?
答案:
- 使用 ART 运行时
- 分代垃圾回收
- 自动内存管理
Q2: 内存泄漏的常见场景?
答案:
- 静态变量持有 Context
- Handler 内存泄漏
- 监听器未注销
- 内部类持有外部类引用
Q3: 如何检测内存泄漏?
答案:
- LeakCanary
- Memory Profiler
- MAT
Q4: 如何优化内存?
答案:
- 避免内存泄漏
- 图片优化
- 对象池
- 数据结构优化
最后更新:2024年