This code return total internal memory size:
public static String getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return formatSize(totalBlocks * blockSize);
}
But this size is without system used memory.
For example, at the GALAXY NOTE 3 is the total internal memory of 32 GB, but this function returns only 26.18 GB.
How to determine the overall internal memory including missing 5.82 GB of system memory?
The basic idea that may work is to compute the first number which is power of two, and it is bigger than the number you got returned from the function.
Ex: 2^5 = 32 > 26
In this case your number is 32. You should convert to integer before comparing obviously.
Related
eg. I have a 1.5 GB data pack. It gives the total sum of 2.0 GB or more than that .
any idea about how to get correct speed every second.
TrafficStats.getTotalRxBytes() does not return your data pack value. It refers to the total received bytes (either wifi/mobile) since the last boot (turning ON phone). For mobile data, it will be TrafficStats.getMobileRxBytes(). More importantly, these values get reset in every reboot of device.
I have a 1.5 GB data pack. It gives the total sum of 2.0 GB or more
than that .
The android system does not know anything about your data pack. You are adding it again and again. When you call TrafficStats.getMobileRxBytes() at a moment, it returns total mobile data received upto this moment since last boot. Following is an explanation. Hope this helps.
// Suppose, you have just rebooted your device, then received 400 bytes and transmitted 300 bytes of mobile data
// After reboot, so far 'totalReceiveCount' bytes have been received by your device over mobile data.
// After reboot, so far 'totalTransmitCount' bytes have been sent from your device over mobile data.
// Hence after reboot, so far 'totalDataUsed' bytes used actually.
long totalReceiveCount = TrafficStats.getMobileRxBytes();
long totalTransmitCount = TrafficStats.getMobileTxBytes();
long totalDataUsed = totalReceiveCount + totalTransmitCount;
Log.d("Data Used", "" + totalDataUsed + " bytes"); // This will log 700 bytes
// After sometime passed, another 200 bytes have been transmitted from your device over mobile data.
totalDataUsed = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
Log.d("Data Used", "" + totalDataUsed + " bytes"); // Now this will log 900 bytes
any idea about how to get correct speed every second.
You cannot get actual speed this way. You can only calculate and show how much bytes have been received/transmitted in a second. All the speed meters in android do the same I think. Something like the following:
class SpeedMeter {
private long uptoNow = 0;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture futureHandle;
public void startMeter() {
final Runnable meter = new Runnable() {
public void run() {
long now = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
System.out.println("Speed=" + (now - uptoNow)); // Prints value for current second
uptoNow = now;
}
};
uptoNow = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
futureHandle = scheduler.scheduleAtFixedRate(meter, 1, 1, SECONDS);
}
public void stopMeter() {
futureHandle.cancel(true);
}
}
And use like this:
SpeedMeter meter = new SpeedMeter();
meter.startMeter();
Although this code is not perfect, however it will suit your needs.
I am using an LRUCache to cache android.graphic.path objects. For that I need to know how many memory the pathes are using for overwriting the sizeOf() method of the LRUCache.
So my question is: How can I calculate the memory usage of a path ?
The difficulty what I already faced is:
The android.graphic.path is not serializable
path is probably stored as bitmap, what I read already ?
Primitivly measuring the memory usage as I did the following (Code) showed me confusing results. Example :
a path with 10'000 lines uses 312 bytes.
10 pathes with 10 lines each uses 992 bytes.
Any hints ?
ArrayList<Path> alPathes=new ArrayList<Path>();
long iAnzahlBigPathes=1;
long iAnzahlOperation4BigPath=20000;
System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();
long lused1=getUsedMemory();
Log.v("Memory4operation","ltotal1 " + lused1);// getMemoryStatus
for(int o=0;o<iAnzahlBigPathes;o++){
Path path=getBigPath(iAnzahlOperation4BigPath);
int iSize=path.toString().length();
alPathes.add(path);
}
System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();
long lused2=getUsedMemory();
Log.v("Memory4operation","ltotal2 " + lused2);// getMemoryStatus
long iDifferenz=lused2-lused1;
Log.v("Memory4operation", "Memory used for path " + iDifferenz + " in bytes");
//float fMemoryforoneline=(float)iDifferenz/(float)iAnzahlSquares;
float fMemoryforoneoperation=(float)iDifferenz/(float)iAnzahlOperation4BigPath/(float)iAnzahlBigPathes;
Log.v("Memory4operation", "" + fMemoryforoneoperation);
public long getUsedMemory(){
final int ltotal = (int) (Runtime.getRuntime().totalMemory());
final int lfree = (int) (Runtime.getRuntime().freeMemory());
return (ltotal - lfree);
}
public Path getBigPath(long iAnzahlOperation4BigPath){
int imin=10;
int imax=1000000;
Path path=new Path();
path.moveTo(randInt(imin,imax), randInt(imin,imax));
for(int i=0;i<iAnzahlOperation4BigPath;i++){
path.lineTo(randInt(imin,imax), randInt(imin,imax));
}
path.close();
return path;
}
Path will usually use hardware rendering when available. So internally it's not stored as a Bitmap but a set of "drawing instructions".
You'll have to look at Path's underlying native implementations (SkPath.cpp) to see how exactly a path is stored internally.
There doesn't seem to be an API available to get the size of the Path.
You're left with:
Look at the implementation and estimate it yourself. Remember that if you save the Path Object to the cache you're caching the instructions and not the rendered result.
Render your path to a bitmap before putting it into the LRUCache. This will save you rendering time. Especially if your paths are expensive to draw. That's most likely what you want anyway
I have the following memory details from the DDMS perspective of Eclipse.
However in spite of implementing the following code, I'm unable to obtain the values shown in the above image.
private void logHeap() {
long maxMemory = Runtime.getRuntime().maxMemory()/ (1024*1024);
long totalMemory = Runtime.getRuntime().totalMemory() / (1024*1024);
long heapSize = Debug.getNativeHeapSize()/(1024*1024);
long allocatedHeapSize = Debug.getNativeHeapAllocatedSize() / (1024*1024);
long freeHeapSize = Debug.getNativeHeapFreeSize() / (1024*1024);
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
df.setMinimumFractionDigits(2);
Log.d(TAG, "debug. =================================");
Log.d(TAG,"Max memory: "+df.format(maxMemory)+" MB");
Log.d(TAG,"Total memory: "+df.format(totalMemory)+" MB");
Log.d(TAG,"Heap Size: "+df.format(heapSize)+" MB");
Log.d(TAG,"Allocated Heapsize: "+df.format(allocatedHeapSize)+" MB");
Log.d(TAG,"Free Heapsize: "+df.format(freeHeapSize)+" MB");
}
I'm getting the following values:
Max Memory : 36.00MB
Total Memory : 7.00 MB
Heap Size : 3.00 MB
allocated heapsize : 3.00 MB
free heapsize : 0.00 MB
Are there any other APIs to obtain the details?
i know how to get free capacity on internal memory and on external storage.
But i want to know max capacity of internal memory and max capacity of external storage, but i can't find any info about it on google
it is possible to achieve it?
thanks
Some new methods were introduced in API 18. This is the code I used to get total storage (internal + external).
private static final long KILOBYTE = 1024;
StatFs internalStatFs = new StatFs( Environment.getRootDirectory().getAbsolutePath() );
long internalTotal;
long internalFree;
StatFs externalStatFs = new StatFs( Environment.getExternalStorageDirectory().getAbsolutePath() );
long externalTotal;
long externalFree;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
internalTotal = ( internalStatFs.getBlockCountLong() * internalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
internalFree = ( internalStatFs.getAvailableBlocksLong() * internalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
externalTotal = ( externalStatFs.getBlockCountLong() * externalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
externalFree = ( externalStatFs.getAvailableBlocksLong() * externalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
}
else {
internalTotal = ( (long) internalStatFs.getBlockCount() * (long) internalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
internalFree = ( (long) internalStatFs.getAvailableBlocks() * (long) internalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
externalTotal = ( (long) externalStatFs.getBlockCount() * (long) externalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
externalFree = ( (long) externalStatFs.getAvailableBlocks() * (long) externalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
}
long total = internalTotal + externalTotal;
long free = internalFree + externalFree;
long used = total - free;
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() * (long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
Source
Also, use this for internal size.
StatFs stat = new StatFs(Environment.getDataDirectory().getPath());
This method will not work on all phones, most phones return the total amount of memory available to the user, less system memory. you might try using the 'df -h' linux command in a c++ method using the NDK, but some phone make that a system (su) command only. So the long and short of it is you can't.
StatFs - Retrieve overall information about the space on a filesystem. This is a wrapper for Unix statvfs().
From API level 18 we use
long getTotalBytes - The total number of bytes supported by the file system.
For older API use
int getBlockCount ()
int getBlockSize ()
StatFs stat = new StatFs(**path**);
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
As path You use Environment.getExternalStorageDirectory(), please review this value. In devices with multiple shared/external storage directories, this directory represents the primary storage that the user will interact with.
You need use string values of path like this:
"/mnt/external_sd/"
"/mnt/extSdCard/"
You can retreive list of all /mnt/ devices and use one of this values.
File allMounted = new File("/mnt/");
if(allMounted.isDirectory()){
String[] dirs = allMounted.list();...}
or something like
var myfile=new Java.IO.File("storage/");
var listOfStorages=myfile.ListFiles();
or
String[] externals = System.getenv("SECONDARY_STORAGE").split(":");
This is more of a generic question which has to do with static variables and the process life cycle.
I have developed a heavy multi threaded signal processing Android app. It is targeted at API level 9 and above, and if I can it will restricted to only dual core devices. This is purely an academic App and not intended for the general user, and has been developed for teaching Digital Signal Processing. So for this reason I am calculating the DFT many times and so forth so there is quite a bit of computation and size allocation required.
I have declared a bunch of static float and double arrays which get used in static functions like in the example below. The complete code is is a bit to big to put here, so the example below just illustrates the idea.
public class SpecMod {
//Example of global static declarations
static double [][] spectrum = null;
static double [][] phaseMat = null;
static float [][] mframes = null;
static float [][] sframes = null;
static double [] mag = null;
static double [] Pxx = null;
static double [] GAMk = null;
static int nfft = 512;
static float nsegs = 560;
//Compute FFT data
public static void calcSpec(int fs, float [] buffer, float f, float g){
//Example of static array memory allocation
sframes = new float[nlen][(int) nsegs];
spectrum = new double[nfft][(int) nsegs];
phaseMat = new double[nfft][(int) nsegs];
mframes = new float[nlen][(int) nsegs];
mag = new double[nfft];
Pxx = new double[nfft];
GAMk = new double[nfft];
}
public static void fillArrays(){
//Example of array manipulation
for (int j = 0; j < nsegs; j++) {
for (int i = 0; i < nfft; i++) {
mag[i] = spectrum[i][j];
phase[i] = phaseMat[i][j];
Pxx[i] = Math.pow(Math.abs(mag[i]), 2);
GAMk[i] = (Pxx[i] / muPnn[i]);
}
}
}
}
The application is working great as it is. The problem lies in different execution times when say the function fillArrays() gets called. The first time the function is called it takes only 4 seconds to complete, however the second and each subsequent time it is run it takes closer to 30 seconds to complete. In log cat you can see that the heap size does increase drastically the second time, but every subsequent time it stays about the same. In MAT the two dimensional array 'spectrum' retains a large portion of heap. This is understandable as it would contain nfft*nsegs (512*560) sized data stored as doubles.
So I am not sure if the time taken is due to the Garbage collector or perhaps the interpreter going into each step of the for loops (strange tho if the first execution is still short). I thought maybe for all other arrays, setting them to non-static weakreferences so the garbage collector can clean them up, but it seems everything I try is to the same time effects.
So the question is, when using large array objects what is the most effective way to allocate space for them. At the moment they are static, but are not final as the size changes frequently due to user preference. Any help would be great thanks.
Note this is just example code, calcSpec() gets called each time the user changes parameters or a new audio file is loaded to compute frequency data 'spectrum', then only after calcSpec is called, the user can call fillArrays(). In terms of profiling, I have been using MemoryAnalyzer and allocation tracker. The odd thing here the time increase is only in fillArrays(). The first execution it take 4seconds, the second (without calling calcSpec() again, so the same spectrum data is used again) it takes 30 seconds. In both Mat and allocation tracker the Retained size and allocation size are the same for every execution.