1、在init.rc中定義一個服務
service drop_caches /sbin/busybox sh /system/bin/flushcache.sh
user root
group root system
disabled
oneshot
flushcache.sh文件內容:
#!/system/bin/busybox sh
/system/bin/log -t pagecache “flush page cache”
echo 1 > /proc/sys/vm/drop_caches
2、在ActivityManagerService.java文件中每個15秒定期檢查內核大小,超過一定值時定期釋放內存,如下:
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
static final int FIRST_COMPAT_MODE_MSG = 300;
static final int FIRST_SUPERVISOR_STACK_MSG = 100;
static ServiceThread sKillThread = null;
static KillHandler sKillHandler = null;
static final int SW_FLUSH_PAGECACHE_MSG = 400;
static final int SW_SEND_MSG_DELAYED = 15*1000;
//static final int SW_MEM_FLUSH_THRESTHOD1 = 80000;// =< 512M 25%
//static final int SW_MEM_FLUSH_THRESTHOD2 = 90000;// > 512M 38%
static final int SW_MEM_FLUSH_THRESTHOD1 = 614400;// 600M 25%
static final int SW_MEM_FLUSH_THRESTHOD2 = 665600;// 650M //768000;//750M 38%
CompatModeDialog mCompatModeDialog;
UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
long mLastMemUsageReportTime = 0;
final class MainHandler extends Handler {
public MainHandler(Looper looper) {
super(looper, null, true);
}
private void flushPageCache() {
MemInfoReader memInfo = new MemInfoReader();
memInfo.readMemInfo();
//Log.d(TAG,"TotalSize=" + memInfo.getTotalSizeKb()*1024 + ", CachedSize=" + memInfo.getCachedSizeKb()*1024 + ",freeSize=" + memInfo.getZramTotalSizeKb()*1024 + ",zramSize=" + memInfo.getZramTotalSizeKb()*1024 + ",kernelSize=" + memInfo.getKernelUsedSizeKb()*1024);//, nativeTotalPss*1024);
Log.d(TAG,"TotalSizeKB=" + memInfo.getTotalSizeKb() + ", CachedSizeKB=" + memInfo.getCachedSizeKb() + ",freeSizeKB=" + memInfo.getFreeSizeKb() + ",zramSizeKB=" + memInfo.getZramTotalSizeKb() + ",kernelSizeKB=" + memInfo.getKernelUsedSizeKb());//, nativeTotalPss*1024);
//if( (memInfo.getTotalSizeKb() <= 524288 && memInfo.getCachedSizeKb() > SW_MEM_FLUSH_THRESTHOD1) ||
// (memInfo.getTotalSizeKb() > 524288 && memInfo.getCachedSizeKb() > SW_MEM_FLUSH_THRESTHOD2) ) {
//524288KB=512M
//getTotalSizeKb<=1.751GB && getCachedSizeKb>600MB or
//getTotalSizeKb>1.600GB && getCachedSizeKb>650MB or
if( (memInfo.getTotalSizeKb() <= 524288 && memInfo.getCachedSizeKb() > SW_MEM_FLUSH_THRESTHOD1) ||
(memInfo.getTotalSizeKb() > 524288 && memInfo.getCachedSizeKb() > SW_MEM_FLUSH_THRESTHOD2) ) {
//Log.d(TAG,"TotalSize="+memInfo.getTotalSizeKb()*1024+", CachedSize="+memInfo.getCachedSizeKb()*1024+",zramKb="+ zramKb*1024+",kernelKb="+kernelKb*1024);//, nativeTotalPss*1024);
SystemProperties.set("ctl.start", "drop_caches");
Log.d(TAG,"start clean cache...");
}
Log.v(TAG,"cached = " + memInfo.getCachedSizeKb() + "KB");
Message msg = Message.obtain();
msg.what = SW_FLUSH_PAGECACHE_MSG;
mHandler.sendMessageDelayed(msg, SW_SEND_MSG_DELAYED);
return;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SW_FLUSH_PAGECACHE_MSG: {
flushPageCache();
break;
}
case UPDATE_CONFIGURATION_MSG: {
final ContentResolver resolver = mContext.getContentResolver();
Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
msg.arg1);
} break;
…………………………………………………………………………………………………………………………………………….
public ActivityManagerService(Context systemContext) {
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();
………………………………………………………………………………………………………………………………………………
new Thread() {
@Override
public void run() {
mProcessCpuTracker.init();
}
}.start();
mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
mStackSupervisor = new ActivityStackSupervisor(this);
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
mRecentTasks = new RecentTasks(this, mStackSupervisor);
mProcessCpuThread = new Thread("CpuTracker") {
@Override
public void run() {
while (true) {
try {
try {
synchronized(this) {
final long now = SystemClock.uptimeMillis();
long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
//Slog.i(TAG, "Cpu delay=" + nextCpuDelay
// + ", write delay=" + nextWriteDelay);
if (nextWriteDelay < nextCpuDelay) {
nextCpuDelay = nextWriteDelay;
}
if (nextCpuDelay > 0) {
mProcessCpuMutexFree.set(true);
this.wait(nextCpuDelay);
}
}
} catch (InterruptedException e) {
}
updateCpuStatsNow();
} catch (Exception e) {
Slog.e(TAG, "Unexpected exception collecting process stats", e);
}
}
}
};
if(SystemProperties.getBoolean("ro.config.low_ram", false) ||
SystemProperties.getBoolean("sys.mem.opt", false) ) {
Message msg = Message.obtain();
msg.what = SW_FLUSH_PAGECACHE_MSG;
mHandler.sendMessage(msg);
}
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
``