两种方法:
第一从是从MemoryInfo中获取:
private void getRamInfo1(){
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
manager.getMemoryInfo(info);
long memory = info.availMem;
long totalMemory = info.totalMem;
Log.d(TAG, "memory: "+memory+" totalMemory "+totalMemory);
}
第二是从节点中获取:
可以用adb看一下节点中的信息
MemTotal: 1638688 kB
MemFree: 544920 kB
MemAvailable: 1111296 kB
Buffers: 16996 kB
Cached: 588952 kB
SwapCached: 0 kB
Active: 426960 kB
Inactive: 457584 kB
Active(anon): 281376 kB
Inactive(anon): 960 kB
Active(file): 145584 kB
Inactive(file): 456624 kB
Unevictable: 2436 kB
Mlocked: 2436 kB
HighTotal: 1188988 kB
HighFree: 255772 kB
LowTotal: 449700 kB
LowFree: 289148 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 28 kB
Writeback: 0 kB
AnonPages: 281048 kB
Mapped: 316056 kB
Shmem: 1860 kB
Slab: 74244 kB
SReclaimable: 21556 kB
SUnreclaim: 52688 kB
KernelStack: 8744 kB
PageTables: 20236 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 819344 kB
Committed_AS: 15876760 kB
VmallocTotal: 499712 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
CmaTotal: 0 kB
CmaFree: 0 kB
先把所有的信息都保存到一个list里面
public List getRamInfo2() {
StringBuffer sb = new StringBuffer();
List arr = null;
try {
BufferedReader burf = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/meminfo")));
String strInfo = "";
arr = new ArrayList<>();
while((strInfo = burf.readLine()) != null){
Log.d(TAG, "getRamInfo3: "+strInfo);
arr.add(strInfo);
}
burf.close();
} catch (Exception e) {
e.printStackTrace();
}
return arr;
}
再将里面的数值提取出来,把0-9的数字提取出来
private String getNumInfo(String strInfo){
StringBuffer sb = new StringBuffer();
char[] chInfo = strInfo.toCharArray();
int size = chInfo.length;
for(int i = 0; i < size; i++){
if(chInfo[i] <= '9' && chInfo[i] >= '0'){
sb.append(chInfo[i]);
}
}
return sb.toString();
}
这两种方式获取到的数值是一样的,但是对比设置,发现可用内存不一样,有很大的差距
用dumpsys meminfo查看一下
Total PSS by category:
148,769K: .so mmap
93,651K: Native
71,767K: .apk mmap
55,802K: .dex mmap
49,099K: Dalvik
41,268K: Unknown
29,717K: .art mmap
29,555K: GL mtrack
27,527K: Other mmap
20,344K: .oat mmap
17,288K: .jar mmap
13,091K: Dalvik Other
12,095K: .ttf mmap
3,264K: Stack
1,894K: Other dev
1,712K: EGL mtrack
436K: Ashmem
0K: Cursor
0K: Gfx dev
0K: Other mtrack
Total RAM: 1,638,688K (status moderate)
Free RAM: 924,257K ( 56,621K cached pss + 462,048K cached kernel + 405,588K free)
Used RAM: 789,278K ( 560,658K used pss + 228,620K kernel)
Lost RAM: -74,847K
Tuning: 128 (large 256), oom 184,320K, restore limit 61,440K (high-end-gfx)
发现将(Free RAM)-(Lost RAM)就是系统设置中显示的了。设置中看一下这些值的获取,在ProcessStatsSummary.java
@Override
public void refreshUi() {
Context context = getContext();
MemInfo memInfo = mStatsManager.getMemInfo();
double usedRam = memInfo.realUsedRam;
double totalRam = memInfo.realTotalRam;
double freeRam = memInfo.realFreeRam;
BytesResult usedResult = Formatter.formatBytes(context.getResources(), (long) usedRam,
Formatter.FLAG_SHORTER);
String totalString = Formatter.formatShortFileSize(context, (long) totalRam);
String freeString = Formatter.formatShortFileSize(context, (long) freeRam);
CharSequence memString;
CharSequence[] memStatesStr = getResources().getTextArray(R.array.ram_states);
int memState = mStatsManager.getMemState();
if (memState >= 0 && memState < memStatesStr.length - 1) {
memString = memStatesStr[memState];
} else {
memString = memStatesStr[memStatesStr.length - 1];
}
mSummaryPref.setAmount(usedResult.value);
mSummaryPref.setUnits(usedResult.units);
float usedRatio = (float)(usedRam / (freeRam + usedRam));
mSummaryPref.setRatios(usedRatio, 0, 1 - usedRatio);
mPerformance.setSummary(memString);
mTotalMemory.setSummary(totalString);
mAverageUsed.setSummary(Utils.formatPercentage((long) usedRam, (long) totalRam));
mFree.setSummary(freeString);
Log.d("refreshUi"," refreshUi "+freeString+" totalString "+totalString);
String durationString = getString(sDurationLabels[mDurationIndex]);
int numApps = mStatsManager.getEntries().size();
mAppListPreference.setSummary(getResources().getQuantityString(
R.plurals.memory_usage_apps_summary, numApps, numApps, durationString));
}
所有的信息都是从MemInfo中取得,接着来看 mStatsManager的初始化
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Bundle args = getArguments();
mStatsManager = new ProcStatsData(getActivity(), icicle != null
|| (args != null && args.getBoolean(ARG_TRANSFER_STATS, false)));
mDurationIndex = icicle != null
? icicle.getInt(ARG_DURATION_INDEX)
: args != null ? args.getInt(ARG_DURATION_INDEX) : 0;
mStatsManager.setDuration(icicle != null
? icicle.getLong(DURATION, sDurations[0]) : sDurations[0]);
}
在ProcStatsData.java中
public void refreshStats(boolean forceLoad) {
if (mStats == null || forceLoad) {
load();
}
pkgEntries = new ArrayList<>();
long now = SystemClock.uptimeMillis();
memTotalTime = DumpUtils.dumpSingleTime(null, null, mStats.mMemFactorDurations,
mStats.mMemFactor, mStats.mStartTime, now);
ProcessStats.TotalMemoryUseCollection totalMem = new ProcessStats.TotalMemoryUseCollection(
ProcessStats.ALL_SCREEN_ADJ, mMemStates);
mStats.computeTotalMemoryUse(totalMem, now);
for (int i = 0; i < mMemStates.length; i++) {
Log.d(TAG, "refreshStats: "+mMemStates[i]);
}
//这里的totalMem时最关键的
mMemInfo = new MemInfo(mContext, totalMem, memTotalTime);
ProcessDataCollection bgTotals = new ProcessDataCollection(
ProcessStats.ALL_SCREEN_ADJ, mMemStates, mStates);
ProcessDataCollection runTotals = new ProcessDataCollection(
ProcessStats.ALL_SCREEN_ADJ, mMemStates, ProcessStats.NON_CACHED_PROC_STATES);
createPkgMap(getProcs(bgTotals, runTotals), bgTotals, runTotals);
if (totalMem.sysMemZRamWeight > 0 && !totalMem.hasSwappedOutPss) {
distributeZRam(totalMem.sysMemZRamWeight);
}
ProcStatsPackageEntry osPkg = createOsEntry(bgTotals, runTotals, totalMem,
mMemInfo.baseCacheRam);
pkgEntries.add(osPkg);
}
接着看代码,在ProcessStats.java中computeTotalMemoryUse方法
//计算内存使用量
public void computeTotalMemoryUse(TotalMemoryUseCollection data, long now) {
data.totalTime = 0;
for (int i=0; i= 3) {
SysMemUsageTable.mergeSysMemUsage(data.sysMemUsage, 0, longs, idx);
longs = tmpLongs;
idx = tmpIndex;
}
}
data.sysMemCachedWeight += longs[idx+SYS_MEM_USAGE_CACHED_AVERAGE]
* (double)memTime;
data.sysMemFreeWeight += longs[idx+SYS_MEM_USAGE_FREE_AVERAGE]
* (double)memTime;
data.sysMemZRamWeight += longs[idx + SYS_MEM_USAGE_ZRAM_AVERAGE]
* (double) memTime;
data.sysMemKernelWeight += longs[idx+SYS_MEM_USAGE_KERNEL_AVERAGE]
* (double)memTime;
data.sysMemNativeWeight += longs[idx+SYS_MEM_USAGE_NATIVE_AVERAGE]
* (double)memTime;
data.sysMemSamples += longs[idx+SYS_MEM_USAGE_SAMPLE_COUNT];
}
}
data.hasSwappedOutPss = mHasSwappedOutPss;
ArrayMap> procMap = mProcesses.getMap();
for (int iproc=0; iproc uids = procMap.valueAt(iproc);
for (int iu=0; iu
接着看getTotalMemUsage方法
public long[] getTotalMemUsage() {
long[] total = new long[SYS_MEM_USAGE_COUNT];
final int N = getKeyCount();
for (int i=0; i
接着是getArrayForKey方法
/**
* Return the raw storage long[] for the given key.
*/
public long[] getArrayForKey(int key) {
assertConsistency();
//从mLong中获取数据
return mParent.mLongs.get(getArrayFromKey(key));
}
mLongs的值时如何add进去的?从Parcel中读取出来的
/**
* Read the data arrays from the parcel.
*/
public void readFromParcel(Parcel in) {
mSequence = in.readInt();
mNextIndex = in.readInt();
Log.d(TAG, "readFromParcel: ",new RuntimeException().fillInStackTrace());
mLongs.clear();
final int N = in.readInt();
for (int i=0; i 0 && mLongs.get(N - 1).length != mNextIndex) {
EventLog.writeEvent(0x534e4554, "73252178", -1, "");
throw new IllegalStateException("Expected array of length " + mNextIndex + " but was "
+ mLongs.get(N - 1).length);
}
}
再看看写的方法
/**
* Write the data arrays to the parcel.
*/
public void writeToParcel(Parcel out) {
out.writeInt(mSequence);
out.writeInt(mNextIndex);
final int N = mLongs.size();
out.writeInt(N);
for (int i=0; i
也就是说系统设置的中显示的已使用内存时通过writeToParcel写到Parcel中,然后再通过readFromParcel从Parcel读取出来的。
主要时利用反射调用,可以获取到总内存大小,已使用的内存
public void getRomInfo() {
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
try {
Method getVolumes = StorageManager.class.getDeclaredMethod("getVolumes");
List