Files
mkdocs/docs/android面试/系统原理/内存管理.md
2026-01-15 11:53:37 +08:00

3.3 KiB
Raw Permalink Blame History

内存管理

目录


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 ProfilerAndroid Studio 工具
// 3. MATMemory Analyzer Tool

内存优化

优化方法

// 1. 避免内存泄漏
// - 使用弱引用
// - 及时释放资源
// - 使用 Application Context

// 2. 图片优化
// - 压缩图片
// - 使用合适格式
// - 及时回收 Bitmap

// 3. 对象池
// - 复用对象
// - 减少创建开销

// 4. 数据结构优化
// - 使用合适的数据结构
// - 避免不必要的对象创建

面试常见问题

Q1: Android 内存管理机制?

答案:

  • 使用 ART 运行时
  • 分代垃圾回收
  • 自动内存管理

Q2: 内存泄漏的常见场景?

答案:

  1. 静态变量持有 Context
  2. Handler 内存泄漏
  3. 监听器未注销
  4. 内部类持有外部类引用

Q3: 如何检测内存泄漏?

答案:

  1. LeakCanary
  2. Memory Profiler
  3. MAT

Q4: 如何优化内存?

答案:

  1. 避免内存泄漏
  2. 图片优化
  3. 对象池
  4. 数据结构优化

最后更新2024年