
1) 【一句话结论】
我参与过一款短视频App的开发,启动慢是因为启动时初始化了大量图片资源,内存泄漏是缓存对象在Activity销毁时未释放,优化后启动时间从3.2秒减少到1.5秒,内存占用从128MB降低到68MB。
2) 【原理/概念讲解】
老师口吻:启动慢的核心问题是“启动时资源初始化逻辑复杂,导致耗时过长”,好比汽车启动后需要加载所有配件(如空调、音响)导致启动慢;内存泄漏则是“对象被强引用或循环引用,GC无法回收”,像房间里的垃圾(未释放的对象)越积越多,导致内存空间不足。
3) 【对比与适用场景】
| 问题类型 | 定位工具 | 分析方法 | 核心目标 |
|---|---|---|---|
| 启动慢 | CPU Profiler | 分析启动阶段各模块耗时分布(如方法调用栈、耗时占比) | 识别耗时最长的初始化模块 |
| 内存泄漏 | Memory Profiler(内存快照) | 对比不同时间点的内存快照,分析对象引用关系(如对象是否被GC回收) | 发现未被回收的对象 |
4) 【示例】
内存泄漏的代码示例(缓存对象未释放):
// 错误:缓存对象在Activity销毁时未释放
class CacheManager {
private static CacheManager instance;
private Map<String, Object> cache;
public static CacheManager getInstance() {
if (instance == null) {
instance = new CacheManager();
}
return instance;
}
public void put(String key, Object value) {
cache.put(key, value);
}
}
// 在Activity中
CacheManager.getInstance().put("user", userObj);
// 销毁时未调用clear,导致对象被强引用
优化后代码:
public class CacheManager {
private static CacheManager instance;
private Map<String, Object> cache;
public static CacheManager getInstance() {
if (instance == null) {
instance = new CacheManager();
}
return instance;
}
public void put(String key, Object value) {
cache.put(key, value);
}
public void clear() {
cache.clear();
cache = null; // 置为null,断开引用
}
}
// 在Activity销毁时调用
@Override
protected void onDestroy() {
super.onDestroy();
CacheManager.getInstance().clear();
}
5) 【面试口播版答案】
“我参与过一款短视频App的开发,其中遇到启动慢和内存泄漏问题。启动慢是因为启动时加载了大量图片资源,导致初始化耗时过长。内存泄漏则是缓存对象在Activity销毁时未释放,通过Memory Profiler生成快照发现该对象持有强引用。我首先用CPU Profiler定位到启动慢的瓶颈在图片资源加载模块,然后优化为启动时只加载必要图片,其他图片使用懒加载;对于内存泄漏,修改代码在Activity销毁时调用缓存对象的clear方法并置为null,确保GC能回收。优化后,启动时间从3.2秒减少到1.5秒,内存占用从128MB降低到68MB。”
6) 【追问清单】
7) 【常见坑/雷区】