在进入android 5.0 Settings应用中进入apps项然后反复的进入某个应用的详细信息页面,
使用adb shell dumpsys meminfo appname查看内存信息,每次进入一次应用详情页面
都会导致内存增加。
要搞清楚这个问题得分析InstalledAppDetails和AppInfoBase的代码,实际上前者继承了
后者。
AppInfoBase继承于SettingsPreferenceFragment,本质上是一个Fragment。
它的onCreate方法如下:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFinishing = false;
mState = ApplicationsState.getInstance(getActivity().getApplication());
mSession = mState.newSession(this);
Context context = getActivity();
......
retrieveAppEntry();
}这里会调用单例类:ApplicationsState对象的newSession方法将自己作为参数传递。
看下ApplicationState的newSession方法:
public Session newSession(Callbacks callbacks) {
Session s = new Session(callbacks);
synchronized (mEntriesMap) {
mSessions.add(s);
}
return s;
}下面是Session的构造函数:
Session(Callbacks callbacks) {
mCallbacks = callbacks;
}Session使用了一个成员变量mCallbacks引用了callbacks即Session引用了AppInfoBase这个Fragment.
同时Session在newSession方法中被加入了ApplicationState类成员变量mSessions中。也就是说ApplicationState
这个类有全局唯一单例类,使用了一个列表保存了每一个AppInfoBase创建的Session,从而间接的持有者每一个
AppInfoBase.如果Session不从mSessions中移除,那么每个AppInfoBase都不会被释放。那么什么时候Session
会从mSessions中移除呢?
Session有个release方法:
public void release() {
pause();
synchronized (mEntriesMap) {
mSessions.remove(this);
}
}在这个方法里将自己移除掉的。
那AppInfoBase会调用这个方法吗?查看整个AppInfoBase的code没有发现调用此方法。因此每个AppInfoBase及其
子类都不会被释放, 导致内存泄露。
这个问题修改的方法就是在AppInfoBase的onDestory方法中调用Session的release方法。
本文分析了Android 5.0系统的Settings应用中出现的内存泄漏问题。通过跟踪AppInfoBase类的实现,发现每当进入应用详情页面时,由于Session对象未正确释放,导致AppInfoBase实例无法被垃圾回收,进而引发内存占用持续增长。
1126

被折叠的 条评论
为什么被折叠?



