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.
Related
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!
I am developing an application that takes up about 12MB of heap on a Galaxy Tab 10.1.
When I test this application on my Samsung Vibrant, however, it provides a little more than 3MB of heap and the % of Heap Size Used is at about 98%.
Could someone explain why this is so, and help me figure out a solution?
I know that VMRuntime is deprecated and I haven't been able to discover an alternative to increase my minimum heap size.
Thanks!
All Android Device has different Heap Size for Application.
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mHeapText = (TextView)findViewById(R.id.mHeapText);
ActivityManager mActivityManager = (ActivityManager)getApplicationContext().getSystemService(ACTIVITY_SERVICE);
int activityMemory = mActivityManager.getMemoryClass();
mHeapText.setText("This Device Able to Use for App " + String.valueOf(activityMemory) + "MB");
}
Check your Samsung Vibrant Heap Size.
I had a user comment that after viewing a bunch of images in my app, it crashes (he believes that it is due to out of memory error). I have the following relevant code:
int themeID = mNav[mPos];
String icon = getThemeData(DbAdapter.KEY_ICON, themeID);
ImageView viewer = (ImageView)findViewById(R.id.viewer);
Bitmap bMap = null;
try {
bMap = getJPG(icon + ".jpg");
} catch (IOException e) {
e.printStackTrace();
}
viewer.setImageBitmap(bMap);
That gets reran as the user flips between images. From here I see that you should call recycle() on bitmaps. Do i need to call it on bMap after setting the image? Or is there some way to pull it from viwer prior to setting the next one?
According to the documentation for recycle (if I call it on bMap) it appears I don't need to use it: This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.
If you need to explicitly call recycle() it probably means that you have memory leak. Calling it is almost never a solution.
Did you try to check your app for potential mmory leak?
To check it you can for example rotate your device a few times and check how the Garbage Collector behaves. You should have something like GC_... freed 211K, 71% free 300K/1024K, external 0K/0K, paused 1ms+1ms in your LogCat nearly every time you rotate. Watch for changes in this part: 300K/1024K. If you don't have memory leaks, the first part should grow and then get smaller after a few GCs. If you have a memory leak, it will grow and grow, to the point of OOM error.
Check out my other answer about a memory leak.
If you're sure you don't have a leak and you're operating on Honeycomb you can increase the heap size accessible for your app like this: android:largeHeap="true" but it's only recommended when you deal with some huuuge bitmaps or videos, so don't overuse it.
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.
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.