# 内存管理

## 目录
- [Android内存管理](#android内存管理)
- [内存分配](#内存分配)
- [垃圾回收](#垃圾回收)
- [内存泄漏](#内存泄漏)
- [内存优化](#内存优化)
- [面试常见问题](#面试常见问题)

---

## Android内存管理

### 内存模型

```java
// Android 内存模型：
// 1. Java 堆：对象实例
// 2. Native 堆：Native 代码分配
// 3. 栈：方法调用、局部变量
// 4. 方法区：类信息、常量
```

### 内存限制

```java
// 不同设备有不同的内存限制
// 低端设备：16MB、32MB
// 中端设备：64MB、128MB
// 高端设备：256MB、512MB+

// 获取内存限制
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int maxMemory = am.getMemoryClass(); // MB
```

---

## 内存分配

### 堆内存分配

```java
// Java 对象分配在堆上
String str = new String("Hello"); // 分配在堆上

// 大对象可能直接分配在老年代
byte[] largeArray = new byte[10 * 1024 * 1024]; // 10MB
```

### 栈内存分配

```java
// 局部变量分配在栈上
public void method() {
    int localVar = 10; // 分配在栈上
    String str = "Hello"; // 引用在栈上，对象在堆上
}
```

---

## 垃圾回收

### GC 类型

```java
// 1. Minor GC：新生代回收
// 2. Major GC：老年代回收
// 3. Full GC：整个堆回收
```

### GC 算法

```java
// ART 使用多种 GC 算法：
// 1. 标记-清除
// 2. 标记-复制
// 3. 标记-整理
// 4. 分代收集
```

### GC 触发时机

```java
// 1. 堆内存不足
// 2. 手动调用 System.gc()
// 3. 对象分配失败
```

---

## 内存泄漏

### 常见泄漏场景

```java
// 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 引用
    }
}
```

### 检测工具

```java
// 1. LeakCanary：自动检测内存泄漏
dependencies {
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
}

// 2. Memory Profiler：Android Studio 工具
// 3. MAT：Memory Analyzer Tool
```

---

## 内存优化

### 优化方法

```java
// 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年*
