先说结论: 使用低adj的apk使用bindService的方式启动新的apk,就可以使新apk的adj值实现100。
1 google gms的apk adj是100
console:/ # ps -A | grep gms
u0_a40 1276 382 1251444 58220 do_epoll_wait 0 S com.google.android.gms.persistent
u0_a40 1438 382 1366508 67448 do_epoll_wait 0 S com.google.android.gms
u0_a40 3309 382 1217588 36128 do_epoll_wait 0 S com.google.android.gms.unstableconsole:/ # cat /proc/1276/oom_score_adj
100
console:/ # cat /proc/1438/oom_score_adj
100
console:/ # cat /proc/3309/oom_score_adj
100
2 当kill掉1276 process, ams会自动启动新persistent进程,其adj也是100
是因为一个service(PersistentBoundBrokerService) 启动的这个process
D Zygote : Forked child process 4919
I ActivityManager: Start proc 4919:com.google.android.gms.persistent/u0a40 for service {com.google.android.gms/com.google.android.gms.chimera.PersistentBoundBrokerService}130|console:/ # cat /proc/4919/oom_score_adj
100
3 通过dumpsys activity p 查找到com.google.android.gms.persistent
显示其oom adj为100
oom adj: max=1001 curRaw=100 setRaw=100 cur=100 set=100,
看到有PersistentBoundBrokerService,是一个servicerecord
*APP* UID 10040 ProcessRecord{1221e37 4919:com.google.android.gms.persistent/u0a40}
user #0 uid=10040 gids={2001, 1005, 3002, 3003, 3001, 3007, 1007, 3006, 50040, 20040, 9997}
mRequiredAbi=armeabi-v7a instructionSet=arm
class=co.g.App
manageSpaceActivityName=co.g.Space
dir=/data/app/~~OVDie3juakjbdsqvQZe_3Q==/com.google.android.gms-nQid-e3R-a4baq8BQGab8Q==/base.apk publicDir=/data/app/~~OVDie3juakjbdsqvQZe_3Q==/com.google.android.gms-nQid-e3R-a4baq8BQGab8Q==/base.apk data=/data/user/0/com.google.android.gms
packageList={com.google.android.gms}
compat={320dpi always-compat}
thread=android.app.IApplicationThread$Stub$Proxy@167737e
pid=4919
lastActivityTime=-7s450ms
startSeq=86
mountMode=DEFAULT
lastPssTime=-7s510ms pssProcState=3 pssStatType=0 nextPssTime=+33m37s435ms
lastPss=51MB lastSwapPss=570KB lastCachedPss=0.00 lastCachedSwapPss=0.00 lastRss=115MB
trimMemoryLevel=0
procStateMemTracker: best=2 (2=2 5.0625x)
lastRequestedGc=-39m30s39ms lastLowMemory=-39m30s39ms reportLowMemory=false
reportedInteraction=true time=-7s565ms
adjSeq=4212 lruSeq=1425
oom adj: max=1001 curRaw=100 setRaw=100 cur=100 set=100
mCurSchedGroup=2 setSchedGroup=2 systemNoUi=false
curProcState=3 mRepProcState=3 setProcState=3 lastStateTime=-22m48s588ms
curCapability=---N setCapability=---N
allowStartFgsState=5
cached=false empty=true
hasStartedServices=true
Services:
......
- ServiceRecord{df148bc u0 com.google.android.gms/.chimera.PersistentBoundBrokerService}
......
mConnections:
- ConnectionRecord{d763b9a u0 CR WACT CAPS com.google.android.gms/com.google.android.location.internal.GoogleLocationManagerService:@31d8845}
......
lastProviderTime=-3m11s647ms
Published Providers:
- com.google.android.gms.auth.account.be.accountstate.AccountStateContentProvider
-> ContentProviderRecord{fb0c0df u0 com.google.android.gms/.auth.account.be.accountstate.AccountStateContentProvider}
......
Connected Providers:
- 3ea4a4d/com.android.providers.settings/.SettingsProvider->4919:com.google.android.gms.persistent/u0a40 s1/1 u0/0 +39m29s753ms
mReceivers:
- ReceiverList{164aa11 4919 com.google.android.gms.persistent/10040/u0 remote:5955a38}
......
lastCompactTime=0 lastCompactAction=0
isFreezeExempt=false isPendingFreeze=false isFrozen=false
BoundClientUids:[10041, 10040, 10039, 1000]
Configuration={1.0 ?mcc?mnc [en_US] ldltr sw540dp w960dp h540dp 320dpi lrg long land television night -touch -keyb/v/h dpad/v winConfig={ mBounds=Rect(0, 0 - 1920, 1080) mAppBounds=Rect(0, 0 - 1920, 1080) mMaxBounds=Rect(0, 0 - 1920, 1080) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.6 fontWeightAdjustment=0}
OverrideConfiguration={0.0 ?mcc?mnc ?localeList ?layoutDir ?swdp ?wdp ?hdp ?density ?lsize ?long ?ldr ?wideColorGamut ?orien ?uimode ?night ?touch ?keyb/?/? ?nav/? winConfig={ mBounds=Rect(0, 0 - 0, 0) mAppBounds=null mMaxBounds=Rect(0, 0 - 0, 0) mWindowingMode=undefined mDisplayWindowingMode=undefined mActivityType=undefined mAlwaysOnTop=undefined mRotation=undefined} ?fontWeightAdjustment}
mLastReportedConfiguration={1.0 ?mcc?mnc [en_US] ldltr sw540dp w960dp h540dp 320dpi lrg long land television night -touch -keyb/v/h dpad/v winConfig={ mBounds=Rect(0, 0 - 1920, 1080) mAppBounds=Rect(0, 0 - 1920, 1080) mMaxBounds=Rect(0, 0 - 1920, 1080) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.6 fontWeightAdjustment=0}
4 然后查找这个PersistentBoundBrokerService service是谁使用或者绑定的呢
同样命令 dumpsys activity p, 看到是system process 与PersistentBoundBrokerService有serviceConnection。
*PERS* UID 1000 ProcessRecord{8489dca 742:system/1000}
user #0 uid=1000 gids={}
mRequiredAbi=null instructionSet=null
dir=/system/framework/framework-res.apk publicDir=/system/framework/framework-res.apk data=/data/system
packageList={com.android.networkstack.inprocess, android, com.android.providers.settings, com.android.networkstack.tethering.inprocess, com.android.location.fused}
compat=null
thread=android.app.ActivityThread$ApplicationThread@a111319
pid=742
lastActivityTime=-3m27s765ms
persistent=true removed=false
startSeq=0
mountMode=NONE
lastPssTime=-22m41s81ms pssProcState=0 pssStatType=1 nextPssTime=+27m55s995ms
lastPss=87MB lastSwapPss=12MB lastCachedPss=0.00 lastCachedSwapPss=0.00 lastRss=123MB
trimMemoryLevel=0
procStateMemTracker: best=0 (0=0 7.59375x)
lastRequestedGc=-- lastLowMemory=-- reportLowMemory=false
reportedInteraction=true time=-6m54s951ms
adjSeq=4212 lruSeq=1
oom adj: max=-900 curRaw=-900 setRaw=-900 cur=-900 set=-900
mCurSchedGroup=2 setSchedGroup=2 systemNoUi=true
curProcState=0 mRepProcState=0 setProcState=0 lastStateTime=-1h3m44s670ms
curCapability=LCMN setCapability=LCMN
allowStartFgsState=0
cached=false empty=false
Services:
- ServiceRecord{154c252 u0 com.android.networkstack.tethering.inprocess/com.android.networkstack.tethering.TetheringService}
- ServiceRecord{c8f2fab u0 com.android.networkstack.inprocess/com.android.server.NetworkStackService}
mConnections:
......
- ConnectionRecord{249ecaf u0 CR FGS com.google.android.gms/.chimera.PersistentBoundBrokerService:@c5dac8e}
......
5 ConnectionRecord的参数 CR 和FGS
ConnectionRecord{249ecaf u0 CR FGS com.google.android.gms/.chimera.PersistentBoundBrokerService:@c5dac8e}
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
sb.append("CR ");
}if ((flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
sb.append("FGS ");
}
6 所以AMS 设置一个apk的adj时会check service对应的serviceConnection, 比较serviceConnection对端的adj,给新apk设置一个合适的adj。
根据serviceConnection设置新apk的adj值的code在OomAdjuster.java,原理OomAdjuster.md中有介绍
frameworks/base/services/core/java/com/android/server/am/OomAdjuster.md
frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
@GuardedBy({"mService", "mProcLock"})
private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
boolean computeClients) {
......
ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections();
for (int conni = serviceConnections.size() - 1;
conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
conni--) {
......
}
......
}