内存分析
一、内存泄漏
(1)Context泄漏
public class NetworkUtil{
private static Context context;
public statci void init(Context context){
NetworkUtil.context=context;
}
}
(2)无效缓存
public class BitmapCache {
private static Map<String, Bitmap> cache = new HashMap<>();
public static void add(String key, Bitmap bitmap) {
cache.put(key, bitmap);
}
}
/**
* 这里简单的将位图放到缓存中,由于并没有保存key的信息,所以后面位图是无法索引到的,因此泄露了
*/
private void leakBitmaps() {
try {
InputStream is = getAssets().open("test.png");
Bitmap bitmap = BitmapFactory.decodeStream(is);
String randomKey = UUID.randomUUID().toString();
BitmapCache.add(randomKey, bitmap);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
(3)Closable
private void leakBitmaps() throws IOException{
InputStream is = getAssets().open("test.png");
Bitmap bitmap = BitmapFactory.decodeStream(is);
String randomKey = UUID.randomUUID().toString();
BitmapCache.add(randomKey, bitmap);
is.close();
}
(4)没有注销的全局监听器
public class EventBus {
private List<Object> subscribers = new ArrayList<>();
private static EventBus instance = new EventBus();
public EventBus getInstance() {
return instance;
}
public void register(Object subscriber) {
subscribers.add(subscriber);
}
public void unregister(Object subscriber) {
subscribers.remove(subscriber);
}
}
二、严格模式检测内存泄漏
ThreadPolicy
监控主线程上的耗时操作
VMPolicy
监控资源泄漏
报告方式
log,dialog,crash等
support from 2.3
/**
* 启用严格模式,可以在运行前检查对象泄露以及在主线程中的耗时行为
*/
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectActivityLeaks()
.detectLeakedClosableObjects()
.detectLeakedSqlLiteObjects()
.detectAll()
.penaltyLog()
.build());
三、Leakcanary
Activity泄漏
监控指定对象
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
public static RefWatcher refWatcher;
refWatcher = LeakCanary.install(this);
/**
* 使用LeakCanary检查指定对象是否有泄露
*/
public static void leakObject() {
LeakContext context = new LeakContext();
querySomething(context);
LeakApplication.refWatcher.watch(context);
}
浪费
图片加载
全尺寸加载
32位真彩色
缓存
预留了过大的缓存
无效缓存没有及时清理
四、分析内存信息
(1)内存类型
数据
虚拟机堆栈,Native堆栈
File mmap
dex files-dex代码映射
so files-so文件映射
resource-app独有资源,系统共享资源
(2)memoryinfo
Debug.MemoryInfo info = new Debug.MemoryInfo();
Debug.getMemoryInfo(info);
(3)adb shell的命令
dumpsys meminfo 3079 -d
(4)showmap 查看文件映射
在使用Webview之后,进程的内存占用会增加相当多,且不会被释放。因此一般可以把包含webview的activity放到独立进程中。
(5)studio内存分析
(6)MAT