5台手机有一台保持在280M占用没有降下来,其他4台都降到150M左右;
没有降下来的手机其占用增长,主要体现在java heap和native heap上面。
XXXX:/ # cat /d/ion/ion_mm_heap | grep Splash
0xc2552cc0 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 139585 -1429625308 -1390939724 Splash Screen com.transsion.filemanagerx#1
0xc2a17480 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 38970 -1419727932 -1311247948 Splash Screen com_ogle.android.apps.nbu.files#0
0xc306a9c0 4239360 0 2 1 3 ca00000 0 3 10 347( 347) allocator@2.0-s 930 80076 -1414703676 -1309183564 Splash Screen com_ogle.android.apps.nbu.files#1
0xc33e9f00 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 130010 -1428007292 -1396797004 Splash Screen com_ogle.android.apps.nbu.files#1
0xc4376d80 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 142932 -1430306588 -1396797004 Splash Screen com.transsion.filemanagerx#0
0xc49b33c0 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 115609 -1426504252 -1397837388 Splash Screen com.transsion.filemanagerx#0
0xc516cd80 4239360 0 2 1 -1 5600000 0 3 10 347( 347) allocator@2.0-s 930 179495 -1421249532 -1311247948 Splash Screen com.transsion.deskclock#1
0xc51f00c0 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 138069 -1423819516 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#1
0xc5ad06c0 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 95400 -1410535580 -1390939724 Splash Screen com.android.chrome#0
0xc6883840 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 172509 -1419610780 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#0
0xc6e8f900 4239360 0 2 1 3 af00000 0 3 10 347( 347) allocator@2.0-s 930 139585 -1429624508 -1390939724 Splash Screen com.transsion.filemanagerx#1
0xc77c03c0 4239360 0 2 1 -1 6000000 0 3 10 347( 347) allocator@2.0-s 930 109328 -1427459228 -1390939724 Splash Screen com.android.contacts#0
0xc780e540 4239360 0 2 1 -1 600000 0 3 10 347( 347) allocator@2.0-s 930 35384 -1414793148 -1397837388 Splash Screen com.transsion.filemanagerx#0
0xc87a0b40 4239360 0 2 1 -1 f300000 0 3 10 347( 347) allocator@2.0-s 930 115609 -1427325180 -1311247948 Splash Screen com.transsion.filemanagerx#0
0xc8bcf9c0 4239360 0 2 1 -1 2900000 0 3 10 347( 347) allocator@2.0-s 930 95400 -1410545980 -1390939724 Splash Screen com.android.chrome#0
0xca7b0c00 4239360 0 2 1 3 2e00000 0 3 10 347( 347) allocator@2.0-s 930 174398 -1408220892 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#0
0xca9e1b40 4239360 0 2 1 -1 4800000 0 3 10 347( 347) allocator@2.0-s 930 38970 -1419726172 -1311247948 Splash Screen com_ogle.android.apps.nbu.files#0
0xcb396900 4239360 0 2 1 3 e800000 0 3 10 347( 347) allocator@2.0-s 930 146290 -1428110588 -1390939724 Splash Screen com.transsion.deskclock#1
0xcbc14480 4239360 0 2 1 -1 5b00000 0 3 10 347( 347) allocator@2.0-s 930 49633 -1414118460 -1309183564 Splash Screen com.transsion.filemanagerx#0
0xcc1aed80 4239360 0 2 1 3 9a00000 0 3 10 347( 347) allocator@2.0-s 930 138069 -1423816956 -1309183564 Splash Screen com_ogle.android.apps.nbu.files#1
0xcc391600 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 31707 -1420034396 -1309183564 Splash Screen com_ogle.android.apps.nbu.files#0
0xcd65e600 4239360 0 2 1 3 7c00000 0 3 10 347( 347) allocator@2.0-s 930 71512 -1388538620 -1390939724 Splash Screen com_ogle.android.apps.nbu.files#1
0xd0611c00 4239360 0 2 1 3 8600000 0 3 10 347( 347) allocator@2.0-s 930 130010 -1428006172 -1396797004 Splash Screen com_ogle.android.apps.nbu.files#1
0xd331a000 4239360 0 2 1 -1 5100000 0 3 10 347( 347) allocator@2.0-s 930 124664 -1427068284 -1396797004 Splash Screen com.android.chrome#0
0xd37c6840 4239360 0 2 1 -1 cf00000 0 3 10 347( 347) allocator@2.0-s 930 142932 -1430303388 -1397837388 Splash Screen com.transsion.filemanagerx#0
0xd46f5180 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 31707 -1393090204 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#0
0xd47b6540 4239360 0 2 1 -1 9400000 0 3 10 347( 347) allocator@2.0-s 930 191145 -1407658140 -1390939724 Splash Screen com.android.documentsui#1
0xd51c1780 4239360 0 2 1 3 a400000 0 3 10 347( 347) allocator@2.0-s 930 192949 -1407646460 -1396797004 Splash Screen com_ogle.android.apps.nbu.files#1
0xd5369780 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 51034 -1420051772 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#1
0xd571a900 4239360 0 2 1 3 c500000 0 3 10 347( 347) allocator@2.0-s 930 192949 -1412016764 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#1
0xd5769180 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 109328 -1427457628 -1311247948 Splash Screen com.android.contacts#0
0xd6664c00 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 35384 -1420228860 -1311247948 Splash Screen com.transsion.filemanagerx#0
0xd83f3600 4239360 0 2 1 3 7700000 0 3 10 347( 347) allocator@2.0-s 930 51034 -1414126780 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#1
0xd866d0c0 4239360 0 2 1 3 de00000 0 3 10 347( 347) allocator@2.0-s 930 146290 -1426112348 -1311247948 Splash Screen com.transsion.deskclock#1
0xd90b09c0 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 179495 -1408206012 -1311247948 Splash Screen com.transsion.deskclock#1
0xd9e92a80 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 174398 -1425692124 -1396797004 Splash Screen com_ogle.android.apps.nbu.files#0
0xda4b7e40 4239360 0 2 1 -1 c00000 0 3 10 347( 347) allocator@2.0-s 930 31707 -1414299964 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#0
0xda81d900 4239360 0 2 1 3 e300000 0 3 10 347( 347) allocator@2.0-s 930 146290 -1426115708 -1311247948 Splash Screen com.transsion.deskclock#1
0xdabe33c0 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 49633 -1389602940 -1309183564 Splash Screen com.transsion.filemanagerx#0
0xdb493e40 4239360 0 2 1 -1 3800000 0 3 10 347( 347) allocator@2.0-s 930 36680 -1414996796 -1397837388 Splash Screen com.transsion.filemanagerx#1
0xdba06b40 4239360 0 2 1 -1 3300000 0 3 10 347( 347) allocator@2.0-s 930 36680 -1420918044 -1309183564 Splash Screen com.transsion.filemanagerx#1
0xdc786240 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 191145 -1407659580 -1390939724 Splash Screen com.android.documentsui#1
0xdcbdbc00 4239360 0 2 1 -1 6c00000 0 3 10 347( 347) allocator@2.0-s 930 118533 -1427061084 -1396797004 Splash Screen com_ogle.android.apps.nbu.files#1
0xdd090240 4239360 0 2 1 -1 7100000 0 3 10 347( 347) allocator@2.0-s 930 118533 -1427388860 -1311247948 Splash Screen com_ogle.android.apps.nbu.files#1
0xdd7dbcc0 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 71512 -1388541180 -1396797004 Splash Screen com_ogle.android.apps.nbu.files#1
0xddec5000 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 124664 -1426597916 -1396797004 Splash Screen com.android.chrome#0
0xde7b5480 4239360 0 2 1 -1 b400000 0 3 10 347( 347) allocator@2.0-s 930 172509 -1419614620 -1397837388 Splash Screen com_ogle.android.apps.nbu.files#0
0xdeabf780 4239360 0 2 1 -1 0 0 3 10 347( 347) allocator@2.0-s 930 80076 -1387374524 -1390939724 Splash Screen com_ogle.android.apps.nbu.files#1
XXXXX:/ # dumpsys window | grep com_ogle
Monkey过程中存在大量的ion buffer泄露
目前遇到的2中情况的占用高的情况:
1, java/native heap占用增长较大(目前出现一台);
2, EGL内存占用增长较大(该情况复现概率相当高
EGL内存泄露过程分析如下:
该泄露,主要体现在Splash screen ion buffer的泄露,该buffer是在app启动过程中show start window(在app visible 之前盖在上面的一张snapshot,该snapshot 是app上次退出时的最后一帧截屏)时申请的graphic buffer,其申请释放流程如下:
1, activity 启动时,wms这边为app 创建一个start window,该window对应到一个surface,并且draw 上一帧页面(该app之前退出的截屏),draw的过程中,会向surfaceFlinger申请相应的graphicbuffer(具体数量根据draw的情况定);
2,activity draw了第一帧自己的UI界面后,通知wms 移除之前的start window,其相应的surface layer也会被销毁,Graphic buffer引用也会释放。
问题出现的情景是:
同一个app,在相当短的时间内,启动了2次不同的activity(100ms+),使上面的流程1走了2次,并且第二次覆盖了第一次的数据,而在流程2里面只remove了后一次的start window,致使泄露一个surface,其相应的graphic buffer也会一直被systemServer引用,得不到释放。
Line 81455: 10-26 20:58:46.198 917 1771 V WindowManager: setAppStartingWindow: token=Token{32fb4a4 ActivityRecord{8f52c36 u0 com.transsion.filemanagerx/.FileManagerSelectPathActivity t9178 f}} pkg=com.transsion.filemanagerx transferFrom=null newTask=false taskSwitch=true processRunning=false allowTaskSnapshot=true
Line 81458: 10-26 20:58:46.198 917 1771 V WindowManager: Creating SplashScreenStartingData
Line 81566: 10-26 20:58:46.215 917 1091 V WindowManager: setAppStartingWindow: token=Token{3db451 ActivityRecord{89e96db u0 com.transsion.filemanagerx/.MainFilemanagerActivity t9178}} pkg=com.transsion.filemanagerx transferFrom=null newTask=false taskSwitch=false processRunning=false allowTaskSnapshot=true
Line 81570: 10-26 20:58:46.216 917 1091 V WindowManager: Creating SplashScreenStartingData
Line 82342: 10-26 20:58:46.324 917 998 V WindowManager: Added starting AppWindowToken{e3f0ee6 token=Token{32fb4a4 ActivityRecord{8f52c36 u0 com.transsion.filemanagerx/.FileManagerSelectPathActivity t9178}}}: startingWindow=Window{98a5005 u0 Splash Screen com.transsion.filemanagerx} startingView=com.android.server.policy.SplashScreenSurface@b036768
Line 83271: 10-26 20:58:46.416 917 1091 V WindowManager: Moving existing starting Window{98a5005 u0 Splash Screen com.transsion.filemanagerx} from AppWindowToken{e3f0ee6 token=Token{32fb4a4 ActivityRecord{8f52c36 u0 com.transsion.filemanagerx/.FileManagerSelectPathActivity t9178}}} to AppWindowToken{e2eeccb token=Token{3db451 ActivityRecord{89e96db u0 com.transsion.filemanagerx/.MainFilemanagerActivity t9178}}}
Line 83338: 10-26 20:58:46.421 917 998 V WindowManager: Added starting AppWindowToken{e2eeccb token=Token{3db451 ActivityRecord{89e96db u0 com.transsion.filemanagerx/.MainFilemanagerActivity t9178}}}: startingWindow=Window{98a5005 u0 Splash Screen com.transsion.filemanagerx} startingView=com.android.server.policy.SplashScreenSurface@16a583c
Line 83872: 10-26 20:58:46.547 917 935 V WindowManager: setAppStartingWindow: token=Token{3db451 ActivityRecord{89e96db u0 com.transsion.filemanagerx/.MainFilemanagerActivity t9178}} pkg=com.transsion.filemanagerx transferFrom=null newTask=false taskSwitch=false processRunning=false allowTaskSnapshot=true
如上log,另一种导致Splash surface泄露case如下:
1,同一个app里面的不同2个activity其他相当靠近;
2,第一个activity通过scheduleAddStartingWindow通过异步的方式,去处理start window的操作;
3,第二个activity启动时,此时第一个activity还处于hidden状态,在transferStartingWindow里面没有任何动作,返回false,同样也会去调用scheduleAddStartingWindow通过异步的方式处理start window操作;
4,第一个activity setVisible时,会触发transferStartingWindow调用,并且将第一个activity的start window复用给第二个activity 的start window,由于步骤3中已经异步处理start window,该覆盖动作会引起如下2中情况的泄露:
a, 第二个activity 异步处理start window在transferStartingWindow之前完成,则步骤3中的异步申请的start window被泄露;
b, 第二个activity异步处理start window在transferStartingWindow之后完成,则第一个activity的start window在步骤4被复用后,被再次覆盖,致使步骤2中的start window被泄露。
针对如上case,提出解决方案:
1, 针对a情况,在transferStartingWindow是,判断被覆盖的appWindowToken的start surface是否已存在(异步处理完成),如果是,则remove掉步骤2中的start window,不做复用处理;
2,针对b情况,在异步申请start window时,判断对应appWindowToken的start surface是否已存在(transferStartingWindow复用了prev的start window),如果是,则不用再次申请start window。
目前的修改方案
frameworks/base/services/core/java/com/android/server/wm/AppWindowContainerController.java
.....
.....
private final Runnable mAddStartingWindow = new Runnable() {
...
...
@Override
public void run() {
final StartingData startingData;
final AppWindowToken container;
...
...
if (surface != null) {
boolean abort = false;
synchronized(mWindowMap) {
// If the window was successfully added, then
// we need to remove it.
if (container.removed || container.startingData == null) {
container.startingWindow = null;
container.startingData = null;
abort = true;
} else {
//modify
//container.startingSurface = surface;
if (mContainer != null && mContainer.startingSurface == null) {
container.startingSurface = surface;
} else {
Slog.w (TAG_WM,"add the starting window with mContainer.startingSurface is not null.");
abort = true;
}
//modify
}
}
...
...
}
...
...
...
}
frameworks/base/services/core/java/com/android/server/wm/AppWindowToken.java
boolean transferStartingWindow(IBinder transferFrom) {
final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
if (fromToken == null) {
return false;
}
//add
if (startingSurface != null || startingData != null){
if (fromToken.getController() != null){
Slog.w (TAG_WM,"call transferStartingWindow with transferTo's startingSurface is not null.");
fromToken.getController().removeStartingWindow();
}
}
//add
final WindowState tStartingWindow = fromToken.startingWindow;
....
....
....
....
}