Error, probably about memory - android

So i was testing my app, and ir ocourred and error in one point, i saw the stack trace and it was on a line that i didn't even change and it was working before. But looking to the stack trace i think the problem is lack of memory.
Here's the line of the error (was in the line setContentView..)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_agencia_figueira);
Button buttonFigueira = (Button) findViewById(R.id.buttonMenu);
buttonFigueira.setOnClickListener(
new Button.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(agenciaFigueira.this, MainActivity.class);
agenciaFigueira.this.startActivity(i);
}
}
);
But one of the lines of the stack trace was : Failed to allocate a 10603020 byte allocation with 4194304 free bytes and 7MB until OOM
If it is lack of memory how can i fix it ? :x

You absolutely need to re-examine your stack traceback ... and possibly add debug statements ... to determine exactly where you're asking for 10MB (and failing). You need to identify the specific resource in question before you can determine a solution.
If you're using an emulator ... then you have the luxury of being able to specify the image's memory size (something you often cannot do with a physical handset). Make sure the emulator has a "reasonable" amount of RAM. 512MB is generally a good number.
Android Studio has excellent tools for checking memory utilization. For example:
https://developer.android.com/tools/debugging/debugging-memory.html
Please post back what you find!

Related

Google I_O 2011 Memory management for Android

After watching the video of Google I/O Memory Management, I come to know about the cause of memory leaks and how to check it by logcat. In one of the example mentioned in the video :
public class MainActivity extends Activity {
class Leaky {
public void doSomething() {
System.out.println("hello");
}
}
static Leaky leak = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (leak == null) {
leak = new Leaky();
}
}
}
When the phone configuration changes(like screen rotation), new activity created and dalvik heap get increased. In this case logcat prints the increased dalvik heap size.
But when tested in Android 4.x device, not getting logcat related to increased dalvik heap size.
Did I miss something?
When the phone configuration changes(like screen rotation), new activity created and dalvik heap get increased
A new activity is created. That may or may not increase the size of the heap. The heap size is only increased if you are getting close to the heap size limit (and the heap can be expanded).
If you watch that video, you will learn how to use MAT to really determine memory leaks, rather than relying upon LogCat messages.

Android heap corruption on USB receive

I'm trying to write a service that communicates with a USB device using USB Interrupt transfer. Basically I'm blocking on UsbConnection.requestWait() in a thread to wait for interrupts transfers in, then pass those to the activity using an intent.
I seem to be having problems when the USB devices sends me a largish number of interrupt packets in a row (about 50). It sometimes works but usually the app crash with a message of that flavor:
02-23 01:55:53.387: A/libc(8460): ### ABORTING: heap corruption detected by tmalloc_small
02-23 01:55:53.387: A/libc(8460): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 8460 (pf.mustangtamer)
it's not always a malloc call that fails, I have seen several flavors of malloc (dlmalloc, malloc_small) as well as dlfree. In every instance I get a Fatal Signal 11 and a reference to 0xdeadbaad so somehow I am corrupting the heap.
It's not obvious from the heap dump what is causing the corruption.
Here is what I believe is the offending code (the problem only occurs when receiving many packets back to back to back):
private class ReceiverThread extends Thread {
public ReceiverThread(String string) {
super(string);
}
public void run() {
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
buffer.clear();
UsbRequest inRequest = new UsbRequest();
inRequest.initialize(mUsbConnection, mUsbEndpointIn);
while(mUsbDevice != null ) {
if (inRequest.queue(buffer, BUFFER_SIZE) == true) {
// (mUsbConnection.requestWait() is blocking
if (mUsbConnection.requestWait() == inRequest){
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
//TODO: use explicit intent, not broadcast
Intent intent = new Intent(RECEIVED_INTENT);
intent.putExtra(DATA_EXTRA, bytes);
sendBroadcast(intent);
} else{
Log.d(TAG, "mConnection.requestWait() returned for a different request (likely a send operation)");
}
} else {
Log.e(TAG, "failed to queue USB request");
}
buffer.clear();
}
Log.d(TAG, "RX thread terminating.");
}
}
Right now the activity is not consuming the intents, I'm trying to get the USB communication to stop crashing before I implement that side.
I'm not seeing how the code above can corrupt the heap, possibly through some non-thread safe behavior. Only one request is queued at a time so I think "buffer" is safe.
My target is a tablet running JB 4.3.1 if that makes a difference.
I'm not seeing anything wrong with this either. You may want to try removing code from your loop and see if it still corrupts the heap to help you zoom on the offending area.
Remember that heap operations are usually delayed, the garbage collector doesn't run immediately, so you could be corrupting it somewhere else, and it's only showing up in this loop because it is very heap intensive.
try to use a larger heap size by setting android:largeHeap="true" in your application manifest.
I would have asked these questions in a comment, but alas, not enough rep.
I see nothing directly wrong with the code above, but I would check the following:
What is BUFFER_SIZE? crazily, I've had very strange problems with UsbRequest.queue() for sizes greater than 15KB. I'm pretty sure that this wouldn't cause your heap corruption, but it could lead to weirdness later. I had to break my requests into multiple calls to queue() to do large reads.
Are you using a bulk USB endpoint? I don't know what your application is, so I cant say for sure if you should be using a bulk endpoint or not, but its the type of endpoint intended for large transfers.
Lastly, when I encountered this 0xdeadbaad problem (detected by tmalloc_large), it had nothing to do with the code I thought was at fault (the code near the malloc) - it was of course a threading issue in which I had JNI native code reading/writing the same buffers on multiple separate threads! Its only that it gets detected when malloc is called, as user3343927 mentioned.

Android traceview not working or only logs 900 ms?

In my default view I have:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Debug.startMethodTracing(Environment.getExternalStorageDirectory()+"/PosLogistics.trace", 1000000000);
and do the stop here:
protected void onStop()
{
super.onStop();
Debug.stopMethodTracing();
}
The android target is 2.2. When running on Motorolla 2.3 I can trace 900 ms. When running on Samsung Galaxy (4.0) and Sony Xperia (4.0) the app closes immediately as it starts up. Last entry from logcat is
02-15 05:25:19.940: I/dalvikvm(8740): TRACE STARTED: '/mnt/sdcard/PosLogistics.trace' 976562KB
According to this thread: Traceview maximum record time? the trace is limited by the device RAM. Might explain the Motorolla 900 ms, but what is the problem with the Galaxy and Xperia?
You are trying to allocate 1000000000 bytes ~ 1GB for trace buffer. I don't think any system will allow you to do that. It is for in memory buffer size, not for disk.
See vm/Profile.cpp line 383.
state->buf = (u1*) malloc(bufferSize);
Skip giving a buffer size. That will default it to 8MB, should be enough for your needs.

Android: Out of memory (VM budget...) on startup, on small percent of total installs

I get a clasical "VM budget excedees memory - out of memory" type error crash report from the Android Market.
I checked the app for memory leaks over and over again. This error happens on a very small percent of total application installs, around 1-2% and it always happens on start-up. The app loads some bitmaps from internal memory for each activity, but does not crash on most devices. I thought all applications had a guaranteed minimum stack size for bitmaps so this should work for every device. Min SDK is 7.
Any reason why ? Does this sound familiar to anyone ?
I had quite a similar problem, and my images were simply too big for some devices.
I have read that you have one image per Activity and I guess this happens when switching from one to another as the newly allocated Drawable cannot fit. What you could do, to save some memory, would be to unload the background image of the Activities that are not shown:
#Override
protected void onResume() {
super.onResume();
Drawable d = loadMyDrawableFromDisk();
setBackgroundDrawable(d);
}
#Override
protected void onPause {
setBackgroundDrawable(null);
super.onPause();
}
It may help as the memory will be freed a few after onPause() is called, and not when the underlying View of your Activity will be unallocated by the system.

Android bitmap allocation weirdness

I'm having some trouble understanding why this code
public class BitmapAllocTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
byte[] b = new byte[20 * 1000 * 1000];
b = null;
Bitmap.createBitmap(2500, 2000, Bitmap.Config.ARGB_8888);
}
}
throws an OutOfMemory exception on a device with a 24mb heap limit. If I comment out either of the allocations it runs fine. I was under the impression that the java vm would try to garbage collect before throwing OutOfMemory exceptions.
I suspect it having to do with android allocating the bitmaps on the native heap.
I posted this on the issue tracker and got this answer:
There are a couple of things going on.
The VM on older devices uses
conservative collection. Most (but
not all) devices running >= 2.0 will
use type-precise GC, but none of them
yet have live-precise GC.
What this means is, the fact that you
set "b = null" doesn't guarantee that
all copies of that reference are gone
-- a copy might still be sitting in a register somewhere, and without
liveness detection the GC can't know
that it will never be used again.
It's also perfectly legal for the
compiler to discard the "b = null"
assignment since you never look at "b"
again.
Bitmap pixel data uses the magical
"external allocation" mechanism rather
than the usual heap allocator.
Sometimes you get unpleasant
interactions.
We're working on fixing all of these
issues.
Link: http://code.google.com/p/android/issues/detail?id=10821
I was under the impression that the java vm would try to garbage collect before throwing OutOfMemory exceptions.
You have to trigger the GC by yourself and retry. I had to do that recently and couldn't figure out another way to do that.

Categories

Resources