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.
Related
I'm developing application for Android(Xamarin). At current moment is like prototype(inside nothing heavy).
I added app7compat support library and also implemented toolbar with navigation Drawer Layout.
I make some test on real device(Samsung Galaxy S4 Active) and it's an like glitch/bug,because when application started,android device monitor showing this :
How that is possible? My activity contains:
Toolbar(with Drawer layout)
Some different controls,like imageView and imageButtons
As i said,that comes from start(i mean that this 86% used memory allocated with strange items,because there is no computing logic).
Why this happens? Thanks!
As guys explained for me,that is ok,because from start application eats 86% of allocated memory(after that if needed, will grow up).
Anothers tip was,to put flag largeHeap and via RunTime(),to see how much memory can be allocated:
Runtime rt = Runtime.getRuntime();
long maxMemory = rt.maxMemory();
Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory/1024/1024));
and my result(Samsung Galaxy S4 Active) was :
512MB
Hope that helps!
I am facing difficulties to get updated available heap size of application after removing some of the large objects.
My requirement is to free the memory once user reach the specific level of heap size. e.g I am using Samsung Tab3 which has 64 Mb heap size for an application.
Application should't go out of memory while viewing images, hence i have restricted 55 MB as max limit for heap size to grow. I am checking available heap size before view image. If the heap size is greater than 55 MB then I remove the some of the images which are recently viewed, so i can get enough memory to load image.
But the problem is that the, after removing images objects, I got the last increased heap size, which is always greater than 55 MB. I also called gc after remove each image, but doesn't affect.
I want the decreased heap size after removing image object.
if heap has reached 55 MB then on each removal heap should decrease, how to get decreased heap size?
I am using following codes to get available heap size.
/**
* This method is used to get currently allocated heap size to application.
*/
public static int getAllocatedHeapSize()
{
DecimalFormat df = new DecimalFormat();
int size = new Double(Runtime.getRuntime().totalMemory()/1048576).intValue();
Log.d("heap", "debug.memory: allocated: " + size + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576)) +"MB free)");
return size;
}
/**
* Check whether free memory is available to store new attachment page
* #return true if available else false
*/
public static boolean isFreeMemoryAvailable()
{
int allocatedHeapSize = getAllocatedHeapSize();
if (allocatedHeapSize > ) {
return false;
}
return true;
}
isFreeMemoryAvailable() method goes in infinite because its not getting updated heap size.
Give me a solution as soon as possible.
Runtime.totalMemory() is not related to how much of the heap that is actually used when called. It returns the actual size of the heap. From the documentation:
Returns the number of bytes taken by the heap at its current size.
Removing objects does not necessarily change the heap size.
You could get the actual usage of the heap by doing:
Runtime.totalMemory() - Runtime.freeMemory();
That said, maybe you should look at storing your images in a android.util.LruCache or something instead of doing this management yourself.
There are several aspects to this question:
1) You might get more reliable and detailed statistics using java management beans, e.g., http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html among other (MemoryMXBean, MemoryPoolMXBean, GarbageCollectorMXBean)
2) You cannot reduce your heap size from within the java application, you can only reduce your usage of the heap.
3) You might consider the usage of Soft References http://docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html. This class enables you to keep references as long as the space is not needed otherwise, and collect it only when absolutely necessary. This way you can limit your heap size, and use soft references to keep data as long as possible but do not impede the GC collecting it if necessary.
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.
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.
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.