Marmalade app: how to determine what memsize needed? - android

On my xperia ray app fails on start when memsize > 50mb (can't alloc so mush). But when memsize = 50mb, app can work around 5 mins, and then fails with message from marmalade, that not enough memory. So how can i find out how mush memory my app needs in peak?
In my .icf file:
MemSize=200000000
#if resolution < 1080x1920
{ [s3e]DispAreaQ < 2073600 }
MemSize=150000000
#if resolution < 640x854
{ [s3e]DispAreaQ < 546560 }
MemSize=52428800
{}

You need to turn on simulator's view matrix option and look under graphics's memory. Check what's the max size it's using. Although simulator's memory usage is different from device's usage, but it'll give you an idea about what memory size is required.
Edit:-
If you need to have different Memsize for debugging you can use MemSizeDebug too, along with MemSize.

Related

Flutter C++ Memory allocation causes jank on raster thread - Android NDK Dart FFI

I have a flutter app which uses Dart ffi to connect to my custom C++ audio backend. There I allocate around 10MB of total memory for my audio buffers. Each buffer has 10MB / 84 of memory. I use 84 audio players. Here is the ffi flow:
C++ bridge:
extern "C" __attribute__((visibility("default"))) __attribute__((used))
void *
loadMedia(char *filePath, int8_t *mediaLoadPointer, int64_t *currentPositionPtr, int8_t *mediaID) {
LOGD("loadMedia %s", filePath);
if (soundEngine == nullptr) {
soundEngine = new SoundEngine();
}
return soundEngine->loadMedia(filePath, mediaLoadPointer, currentPositionPtr, mediaID);
}
In my sound engine I launch a C++ thread:
void loadMedia(){
std::thread{startDecoderWorker,
buffer,
}.detach();
}
void startDecoderWorker(float*buffer){
buffer = new float[30000]; // 30000 might be wrong here, I entered a huge value to just showcase the problem, the calculation of 10MB / 84 code is redundant to the code
}
So here is the problem, I dont know why but when I allocate memory with new keyword even inside a C++ thread, flutters raster thread janks and I can see that my flutter UI janks lots of frames. This is also present in performance overlay as it goes all red for 3 to 5 frames with each of it taking around 30 40ms. Tested on profile mode.
Here is how I came to this conclusion:
If I instantly return from my startDecoderWorker without running new memory allocation code, when I do this there is 0 jank. Everything is smooth 60fps, performance overlay doesnt show me red bars.
Here are some screenshots from Profile mode:
The actual cause, after discussions (in the comments of the question), is not because the memory allocation is too slow, but lie somewhere else - the calculations which will be heavy if the allocation is big.
For details, please refer to the comments and discussions of the question ;)

What does it mean if totalMemory is small, but totalPss is very huge?

We have a problem with our app. Over time we have noticed that the totalPss value gets very large (depending on the device, it will be 300-700Mb):
int pid = android.os.Process.myPid();
int pids[] = new int[1];
pids[0] = pid;
android.os.Debug.MemoryInfo[] memoryInfoArray = activityManager.getProcessMemoryInfo(pids);
if (memoryInfoArray.length > 0)
{
android.os.Debug.MemoryInfo thisProcessMemoryInfo = memoryInfoArray[0];
Log.d("totalPss", thisProcessMemoryInfo.getTotalPss()+"");
}
Here is a graph showing results from a typical run:
But, at the same time, the totalMemory value never gets very large (40-50Mb at max, but falls to 10Mb after GC).
Log.d("totalMem", Runtime.getRuntime().totalMemory()+"");
Here is a graph showing that from the same run as above (please ignore the units, it is actually in bytes):
getMemoryClass for this device indicates that we have 192Mb available for the app:
Log.d("getMemoryClass", activityManager.getMemoryClass()+"");
Our memory usage pattern is to make a number of large allocations over time which are frequently released. After a long time of this, a large allocation will fail which typically causes the app to fail.
It seems like we are probably having fragmentation, does this seem correct? Can we resolve this by using the largeHeap attribute (my intuition is that it would not)? Are there any tools to help diagnose this more certainly?

How can Android leak memory while the App's memory remains stable

Android runs out of memory and restarts applications even though the amount of memory that Runtime reports that it is using remains nearly constant.
How can an Android phone run out of memory when the amount of memory that it's applications use remains nearly constant?
The following line of code returns a nearly constant value between 4 and 5 MB, but Android's App Manager shows that the running app is leaking about 1 megabyte per iteration and after a while, Android starts shutting down process because memory is low.
(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())
I see similar results when I use Eclipse's Memory Analyzer Tool to view HPROF or in Android's Heap tool to view the heap. I didn't see a huge block of memory being allocated in Android's Allocation Tracker either.
So, the big questions for me are:
1) How can the memory as reported in an app and the memory as reported by android be out of synch?
2) I'll give full credit for pointers that get me past this memory leak in the test code. (I'm happy to provide the full test code.)
//This is an excerpt from the case.
import es.vocali.util.AESCrypt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
...
byte[] data = getData(ONE_MEGABYTE);
AESCrypt aesCrypt = new AESCrypt(PASSWORD);
ByteArrayOutputStream baos = new ByteArrayOutputStream(ONE_MEGABYTE+ONE_KILOBYTE);
//Each iteration leaks approximately ONE_MEGABYTE
for(int i = 0; i < NUMBER_OF_ENCRYPTIONS; i++) {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
aesCrypt.encrypt(2, bais, baos);
bais.close();
bais = null;
baos.reset();
}

Android Soundpool problems

I've got an app on the Android Market and have been using the SoundPool classes for the sound effects. I've noticed that, of all the parts of the Android API, this seems to have caused me the most problems. For example:
HTC Desire has problems playing WAV files (this causes it to lock up randomly). Using .ogg files fixes this
On the Droid, if you exceed the number of channels in the init setup call:
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
the handset would lock up. If you can imagine the difficulty in debugging that! On a handset I don't own. It required a lot of selfless help from my customers. Changing the '4' to '16' eliminated the problem. I have no doubt that if 16 sounds were played simultaneously it would still crash. Thankfully the chances of that are low.
Also getting random crashes on various devices. I have got a catlog from one of my customers which has 'Heap overflow' errors pertaining to playing sounds.
I have now changed my sound manager to use MediaPlayer. This seems to be working out fine for now. I am just wondering if any other developers are experiencing these problems?
It seems AudioFlinger can have up to 1 Mb worth of audio going on at any given time.
The heap errors occur if this limit is exceeded. This guess is based on some code I found in AudioFlinger source code:
AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
: RefBase(),
mAudioFlinger(audioFlinger),
mMemoryDealer(new MemoryDealer(1024*1024)),
mPid(pid)
{
// 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
}
And this:
size_t size = sizeof(audio_track_cblk_t);
size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
if (sharedBuffer == 0) {
size += bufferSize;
}
mCblkMemory = client->heap()->allocate(size);
if (mCblkMemory != 0) {
...
} else {
LOGE("not enough memory for AudioTrack size=%u", size);
client->heap()->dump("AudioTrack");
}
Anyone else better informed?

How to measure VRAM consumption on Android?

I want to acquire怀Android Device VRAM size.
Is there a method for acquisition from the program?
Let's do some calculation using Nexus One:
Screen resolution is 480x800. So minimum required video memory size would be:
400 * 800 * 4 bytes = 1536000 bytes
Assuming that driver may (and normally should) use several buffers, we should also expect values like:
1536000 * 2 bytes = 3072000 bytes
1536000 * 3 bytes = 4608000 bytes
etc...
It would be weird to have values that are not multiple of 1536000 (or W x H x 4 in general).
After some searches on Android internals I've found this documentation :
...Android makes two requirements of the driver: a linear address space of mappable memory that it can write to directly...accessing the driver by calling open on /dev/fb0...
So I tried and take size of /dev/graphics/fb0 file (on my device there is no /dev/fb0).
But a direct approach doesn't work:
File file = new File("/dev/graphics/fb0");
file.length(); // ==0, doesn't work, no read access
Using next trick you can get actual size of fb0:
>adb pull /dev/graphics/fb0
1659 KB/s (4608000 bytes in 2.712s)
Video memory is ~4mb (Nexus One). Let's check if this is multiple of Nexus screen size:
4608000/1536000 = 3
It looks like a right value. And we also can say that driver uses three screen buffers.
So, as a conclusion, you can detect video memory size using adb, but you can't use this approach from your android application in runtime due to file access restrictions.
You typically do not have a dedicated "VRAM" on mobile devices. At least you don't have it with PowerVR architectures (wich totally dominate the market with their MBX and SGX cores).
That is, the OpenGL driver allocates normal RAM until you run out of it, and the more you allocate the less you have left for your application.
The Android/OpenGL APIs don't offer explicit methods to read the VRAM size from a given device.
Poor man solution:
You could try to infer the VRAM size in an empiric way adding 1MB texture until you get an out of memory error from gl.glGetError().
From your "dmesg" output u can read off the VRAM, so for my Tablet:
> [ 0.000000] Machine: TDM3730 [ 0.000000] Reserving 12582912
> bytes SDRAM for VRAM
>
> 7>[ 3.929962] VRAM: checking region 9f400000 3072
> <4>[ 3.929992] Failed. Allocating 4194304 bytes for fb 0
> <7>[ 3.935333] VRAM: alloc mem type 0 size 4194304 paddr dec2bd4c
> <7>[ 3.935485] VRAM: checking region 9f400000 3072
> <7>[ 3.935485] VRAM: found 9f400000, end a0000000
> <6>[ 3.936584] android_usb gadget: high speed config #1: android
> <4>[ 3.960113] allocating 4194304 bytes for fb 1
or details at:
http://pastebin.com/jQSXQqHh
Is simple just count how many Mb ram that from usable to real capacity of the ram, example for my lenovo a369i has 512 RAM Module, but in setting app only showing 471 Mb usable so the 41Mb left is reserved for the GPU, so the conclusion is my a369i has 41Mb vram
This method is based from shared graphics memory (wiki)
I suspect that android.os.StatFs is what you're looking for:
http://developer.android.com/reference/android/os/StatFs.html

Categories

Resources