android如何获取RAM和ROM使用情况
1.获取ram大小两种方法:第一从是从MemoryInfo中获取:private void getRamInfo1(){ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);ActivityManager.MemoryInfo info = new ActivityM...
·
1.获取ram大小
两种方法:
第一从是从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<String> getRamInfo2() {
StringBuffer sb = new StringBuffer();
List<String> 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<STATE_COUNT; i++) {
data.processStateWeight[i] = 0;
data.processStatePss[i] = 0;
data.processStateTime[i] = 0;
data.processStateSamples[i] = 0;
}
for (int i=0; i<SYS_MEM_USAGE_COUNT; i++) {
data.sysMemUsage[i] = 0;
}
data.sysMemCachedWeight = 0;
data.sysMemFreeWeight = 0;
data.sysMemZRamWeight = 0;
data.sysMemKernelWeight = 0;
data.sysMemNativeWeight = 0;
data.sysMemSamples = 0;
//这句最为关键
final long[] totalMemUsage = mSysMemUsage.getTotalMemUsage();
for (int is=0; is<data.screenStates.length; is++) {
for (int im=0; im<data.memStates.length; im++) {
int memBucket = data.screenStates[is] + data.memStates[im];
int stateBucket = memBucket * STATE_COUNT;
long memTime = mMemFactorDurations[memBucket];
if (mMemFactor == memBucket) {
memTime += now - mStartTime;
}
data.totalTime += memTime;
final int sysKey = mSysMemUsage.getKey((byte)stateBucket);
long[] longs = totalMemUsage;
int idx = 0;
if (sysKey != SparseMappingTable.INVALID_KEY) {
final long[] tmpLongs = mSysMemUsage.getArrayForKey(sysKey);
final int tmpIndex = SparseMappingTable.getIndexFromKey(sysKey);
if (tmpLongs[tmpIndex+SYS_MEM_USAGE_SAMPLE_COUNT] >= 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<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
for (int iproc=0; iproc<procMap.size(); iproc++) {
SparseArray<ProcessState> uids = procMap.valueAt(iproc);
for (int iu=0; iu<uids.size(); iu++) {
final ProcessState proc = uids.valueAt(iu);
proc.aggregatePss(data, now);
}
}
}
接着看getTotalMemUsage方法
public long[] getTotalMemUsage() {
long[] total = new long[SYS_MEM_USAGE_COUNT];
final int N = getKeyCount();
for (int i=0; i<N; i++) {
final int key = getKeyAt(i);
//这个addData就是添加进去的数据
final long[] addData = getArrayForKey(key);
final int addOff = SparseMappingTable.getIndexFromKey(key);
SysMemUsageTable.mergeSysMemUsage(total, 0, addData, addOff);
}
return total;
}
接着是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<N; i++) {
final int size = in.readInt();
final long[] array = new long[size];
readCompactedLongArray(in, array, size);
//添加到mLongs中
mLongs.add(array);
}
// Verify that last array's length is consistent with writeToParcel
if (N > 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<N-1; i++) {
final long[] array = mLongs.get(i);
out.writeInt(array.length);
writeCompactedLongArray(out, array, array.length);
}
// save less for the last one. upon re-loading they'll just start a new array.
final long[] lastLongs = mLongs.get(N-1);
out.writeInt(mNextIndex);
writeCompactedLongArray(out, lastLongs, mNextIndex);
}
也就是说系统设置的中显示的已使用内存时通过writeToParcel写到Parcel中,然后再通过readFromParcel从Parcel读取出来的。
2.获取rom大小
主要时利用反射调用,可以获取到总内存大小,已使用的内存
public void getRomInfo() {
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
try {
Method getVolumes = StorageManager.class.getDeclaredMethod("getVolumes");
List<Object> getVolumeInfo = (List<Object>) getVolumes.invoke(storageManager);
long total = 0L, used = 0L;
int version = Build.VERSION.SDK_INT;
for (Object obj : getVolumeInfo) {
Field getType = obj.getClass().getField("type");
int type = getType.getInt(obj);
Log.d(TAG, "type: " + type);
if (type == 1) {//TYPE_PRIVATE
long totalSize = 0L;
//获取内置内存总大小
if (version >= Build.VERSION_CODES.O) {
Method getFsUuid = obj.getClass().getDeclaredMethod("getFsUuid");
String fsUuid = (String) getFsUuid.invoke(obj);
反射调用getTotalBytes方法
totalSize = getTotalSize(fsUuid);
//反射调用getFreeBytes方法
long free = getFreeBytes(fsUuid);
Log.d(TAG, "query:totalSize " + totalSize + " free " + (totalSize - free));
} else if (version >= Build.VERSION_CODES.N_MR1) {//7.1.1
//5.0 6.0 7.0没有
Method getPrimaryStorageSize = StorageManager.class.getMethod("getPrimaryStorageSize");
totalSize = (long) getPrimaryStorageSize.invoke(storageManager);
}
long systemSize = 0L;
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
if (readable) {
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
Log.d(TAG, "query: " + f.getAbsolutePath());
if (totalSize == 0) {
//获取data分区的大小
totalSize = f.getTotalSpace();
}
String _msg = "剩余总内存:getTotalSpace " + f.getTotalSpace() + " " + getUnit(f.getTotalSpace()) + "\n可用内存:" + getUnit(f.getFreeSpace()) + "\n已用内存:" + getUnit(f.getTotalSpace() - f.getFreeSpace());
Log.d(TAG, _msg);
systemSize = totalSize - f.getTotalSpace();
used += totalSize - f.getFreeSpace();
total += totalSize;
}
Log.d(TAG, "totalSize = " + getUnit(totalSize) + " ,used(with system) = " + getUnit(used) + " ,free = " + getUnit(totalSize - used));
} else if (type == 0) {//TYPE_PUBLIC
//外置存储
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
if (readable) {
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
/* used += f.getTotalSpace() - f.getFreeSpace();
total += f.getTotalSpace();*/
long test1 = f.getTotalSpace() - f.getFreeSpace();
long test2 = f.getTotalSpace();
Log.d(TAG, "query: TYPE_PUBLIC test1 " + test1 + " total test2 " + test2);
}
} else if (type == 2) {//TYPE_EMULATED
}
}
Log.d(TAG, "总内存 total = " + total + " " + getUnit(total) + " ,已用 used(with system) = " + used + " " + getUnit(used) + "\n可用 available = " + (total - used) + " " + getUnit(total - used));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* API 26 android O
* 获取总共容量大小,包括系统大小
*/
@RequiresApi(api = Build.VERSION_CODES.O)
public long getTotalSize(String fsUuid) {
try {
UUID id;
if (fsUuid == null) {
id = StorageManager.UUID_DEFAULT;
} else {
id = UUID.fromString(fsUuid);
}
StorageStatsManager stats = getSystemService(StorageStatsManager.class);
return stats.getTotalBytes(id);
} catch (NoSuchFieldError | NoClassDefFoundError | NullPointerException | IOException e) {
e.printStackTrace();
return -1;
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
public long getFreeBytes(String fsUuid) {
try {
UUID id;
if (fsUuid == null) {
id = StorageManager.UUID_DEFAULT;
} else {
id = UUID.fromString(fsUuid);
}
StorageStatsManager stats = getSystemService(StorageStatsManager.class);
return stats.getFreeBytes(id);
} catch (NoSuchFieldError | NoClassDefFoundError | NullPointerException | IOException e) {
e.printStackTrace();
return -1;
}
}
/**
* 单位转换
*/
private String getUnit(float size) {
int index = 0;
while (size > 1000 && index < 4) {
size = size / 1000;
index++;
}
return String.format(Locale.getDefault(), " %.2f %s", size, units[index]);
}
更多推荐
已为社区贡献9条内容
所有评论(0)