Skip to content

性能分析与优化

字数统计:约 9000 字
难度等级:⭐⭐⭐⭐
面试重要度:⭐⭐⭐⭐


目录

  1. 性能分析工具
  2. CPU 性能分析
  3. 内存性能分析
  4. 网络性能分析
  5. 电池性能分析
  6. 面试考点

1. 性能分析工具

1.1 Android Profiler

打开方式:
View → Tool Windows → Profiler

分析维度:
- CPU - 处理器使用
- Memory - 内存使用
- Energy - 电池消耗
- Network - 网络流量

1.2 Perfetto

使用 Perfetto:
1. 打开 https://ui.perfetto.dev
2. 连接设备
3. 开始录制
4. 分析系统轨迹

优势:
- 系统级追踪
- 低开销
- 详细数据

1.3 Systrace

bash
# 使用 Systrace
python systrace.py --time=10 -o trace.html sched freq idle am wm gfx view

# 分析 trace.html 文件

2. CPU 性能分析

2.1 CPU Profiler

使用步骤:
1. 打开 CPU Profiler
2. 选择采样模式
3. 开始录制
4. 执行操作
5. 停止分析

2.2 方法追踪

kotlin
// 手动追踪
class PerformanceTracking {
    
    fun loadData() {
        Trace.beginSection("loadData")
        try {
            // 代码
        } finally {
            Trace.endSection()
        }
    }
    
    suspend fun fetchData() = withContext(Dispatchers.IO) {
        Trace.beginSection("fetchData")
        try {
            // 代码
        } finally {
            Trace.endSection()
        }
    }
}

2.3 优化技巧

kotlin
// 1. 避免主线程阻塞
// ❌ 错误
fun loadData() {
    val data = database.query() // 主线程查询
}

// ✅ 正确
suspend fun loadData() = withContext(Dispatchers.IO) {
    database.query()
}

// 2. 减少对象创建
// ❌ 错误
fun formatList(items: List<Item>): String {
    var result = ""
    for (item in items) {
        result += item.name + ", " // 每次创建新 String
    }
    return result
}

// ✅ 正确
fun formatList(items: List<Item>): String {
    return buildString {
        items.forEach { append(it.name).append(", ") }
    }
}

// 3. 使用合适的数据结构
// 频繁查找用 HashMap
val map = hashMapOf<Int, String>()

// 有序数据用 Array
val array = arrayOf(1, 2, 3)

3. 内存性能分析

3.1 Memory Profiler

使用步骤:
1. 打开 Memory Profiler
2. 查看内存使用
3. 捕获堆转储
4. 分析对象
5. 查找泄漏

3.2 内存泄漏检测

kotlin
// 常见泄漏场景
class MemoryLeaks {
    
    // 1. 静态集合
    companion object {
        private val cache = mutableListOf<Any>() // 泄漏
    }
    
    // 2. 非静态内部类
    inner class InnerClass {
        // 持有外部类引用
    }
    
    // 3. 未注销监听器
    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {}
    }
    // 忘记 unregisterReceiver
}

3.3 优化技巧

kotlin
// 1. 使用 WeakReference
class WeakCache {
    private val cache = WeakHashMap<Key, Value>()
}

// 2. 及时释放资源
class ResourceReleasing {
    private var bitmap: Bitmap? = null
    
    fun release() {
        bitmap?.recycle()
        bitmap = null
    }
}

// 3. 使用 LruCache
class LruCacheExample {
    private val cache = LruCache<String, Bitmap>(16)
}

// 4. 避免 Bitmap 过大
fun loadBitmap(path: String): Bitmap {
    val options = BitmapFactory.Options().apply {
        inSampleSize = calculateInSampleSize(this, 100, 100)
    }
    return BitmapFactory.decodeFile(path, options)
}

4. 网络性能分析

4.1 Network Profiler

使用步骤:
1. 打开 Network Profiler
2. 查看请求列表
3. 分析请求详情
4. 查看响应内容

4.2 优化技巧

kotlin
// 1. 使用连接池
val client = OkHttpClient.Builder()
    .connectionPool(ConnectionPool(10, 5, TimeUnit.MINUTES))
    .build()

// 2. 启用缓存
val client = OkHttpClient.Builder()
    .cache(Cache(cacheDir, 10 * 1024 * 1024)) // 10MB
    .build()

// 3. 请求合并
suspend fun fetchMultipleData(): Triple<Data1, Data2, Data3> {
    return coroutineScope {
        val d1 = async { api.getData1() }
        val d2 = async { api.getData2() }
        val d3 = async { api.getData3() }
        
        Triple(d1.await(), d2.await(), d3.await())
    }
}

// 4. 数据压缩
// 使用 GZIP
// 使用 Protobuf 代替 JSON

5. 电池性能分析

5.1 Energy Profiler

使用步骤:
1. 打开 Energy Profiler
2. 查看电量消耗
3. 识别高耗电操作
4. 优化

5.2 优化技巧

kotlin
// 1. 减少网络请求
// 批量请求
// 使用推送代替轮询

// 2. 优化定位
val locationRequest = LocationRequest.create().apply {
    interval = 60000 // 1 分钟
    fastestInterval = 30000
    priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
}

// 3. 使用 WorkManager
val work = OneTimeWorkRequestBuilder<MyWorker>().build()
WorkManager.getInstance().enqueue(work)

// 4. 优化唤醒锁
val wakeLock = powerManager.newWakeLock(
    PowerManager.PARTIAL_WAKE_LOCK,
    "MyApp::WakeLock"
).apply {
    acquire(10*60*1000L) // 10 分钟
}

6. 面试考点

6.1 基础概念

Q1: Android Profiler 能分析什么?

答案要点:
- CPU 使用率
- 内存使用
- 网络流量
- 电池消耗

Q2: 如何检测内存泄漏?

答案要点:
1. Memory Profiler 捕获堆转储
2. 分析对象引用
3. 使用 LeakCanary
4. 查找 GC Roots

6.2 实战问题

Q3: 如何优化启动速度?

答案要点:
1. 延迟初始化
2. 异步加载
3. 减少主线程工作
4. 使用 App Startup
5. 优化布局

Q4: 如何优化列表滚动?

答案要点:
1. ViewHolder 复用
2. 图片加载优化
3. 减少布局层级
4. 使用 DiffUtil
5. 预加载数据

参考资料


本文完,感谢阅读!