iOS equivalent to increasing heap size - android

iOS apps (for the most part) is written in Objective-C, which is a subset of C, and is therefore a data managed language, unlike Android/Java.
In Android, you have the ability to increase heap size by simply adding this one line in the XML android manifest:
<application android:largeHeap="true"/>
Is there an iOS version to doing something like this?

Well in iOS you don't have any control over the memory.
It is all managed by the kernel. So you cannot increase the heap size.
As pointed out in the comments, memory management has a different notion in iOS.
You get as many memory as available but if the app uses to much memory it will be killed by the system.
Now that you explained your goal, you shouldn't download large files into memory, this will cause trouble. Instead you should save it directly to the disk as you get the response.

Take a look at Apple's "Memory Usage Performance Guidelines" for an explanation of how iOS doesn't manage swap space.
Although OS X supports a backing store, iOS does not. In iPhone applications, read-only data that is already on the disk (such as code pages) is simply removed from memory and reloaded from disk as needed. Writable data is never removed from memory by the operating system. Instead, if the amount of free memory drops below a certain threshold, the system asks the running applications to free up memory voluntarily to make room for new data. Applications that fail to free up enough memory are terminated.
iOS attempts to provide each application with as much of the device's memory as the OS can spare. However each application is limited to the device's physical memory. There is no option to allocated larger blocks and expect them to be swapped to disk as needed.
Manipulating the heap size in iOS is therefore not a meaningful concept. Each app already has the largest heap the OS can provide. Instead apps must attempt to minimize their memory footprint to remain within the available space on the host device. This means purging in-memory caches in response to memory warnings, streaming access to resources on disk (as #CouchDeveloper suggested in a comment), and minimizing the amount of memory used overall.
As an additional complication iOS attempts to keep memory in use. Unused memory is wasted capacity and users may be better served by the OS keeping more applications suspended and in memory rather than terminated. As a result attempting to measure available free memory does not give a meaningful result. As the device runs low on free memory other applications will reduce their use in response to memory warnings or by being terminated completely.

Related

how much memory usage is reasonable for a typical android application

I'm sorry for asking this duplicate question. But as you can see in that link the topic is saying one thing but the content is about something else.
I'm not asking how to manage or how to monitor the memory, just want to know how much memory usage you call a memory friendly app. And from what range you consider as using too much memory.
Thank you
Short Answer: As low as possible.
Long Answer: To allow multiple running processes, Android sets a hard limit on the heap size alloted for each app. The exact heap size limit varies between devices based on how much RAM the device has available overall. If your app has reached the heap capacity and tries to allocate more memory, the system throws an OutOfMemoryError, and to avoid running out of memory, you can to query the system to determine how much heap space you have available on the current device.
You can query the system for this figure by calling getMemoryInfo(), which provides information about the device's current memory status, including available memory, total memory, and the memory threshold—the memory level at which the system begins to kill processes.
For more details, see this
https://developer.android.com/topic/performance/memory

Android: why is memory usage for one application drasmatically larger than allowable memory for one process

As I researched, Android allocates limit memory for each process, maybe range from 16MB to 24MB for each one. Here is reference
Nevertheless when I view memory usage for one application in setting, I often see one normal application costs hundred megabytes for memory (on one process). There is a conflict here that I cannot understand.
Thanks :)
NDK code can use more system RAM than can a single Dalvik/ART process. Also, the app might be using more than one process, or it might be using android:largeHeap to request an above-normal heap size.

What are advantages of setting largeHeap to true?

I have an application with large number of classes & also many libraries are included, I am setting android:largeHeap="true" as i am getting memory issue, My Manifest file code is attached.
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="My Huge Application"
android:largeHeap="true"
android:logo="#drawable/logo"
android:screenOrientation="portrait"
android:theme="#style/AppTheme" >
</application>
I had to ask that is this a good practice?
Kindly suggest advantages and disadvantages (pros and cons) of using it.
Way too late for the party here, but i will offer my 0.02$ anyways.
It's not a good idea to use android:largeHeap="true" here's the extract from google that explains it,
However, the ability to request a large heap is intended only for a
small set of apps that can justify the need to consume more RAM (such
as a large photo editing app). Never request a large heap simply
because you've run out of memory and you need a quick fix—you should
use it only when you know exactly where all your memory is being
allocated and why it must be retained. Yet, even when you're confident
your app can justify the large heap, you should avoid requesting it to
whatever extent possible. Using the extra memory will increasingly be
to the detriment of the overall user experience because garbage
collection will take longer and system performance may be slower when
task switching or performing other common operations.
here's the complete link of the documentation
https://developer.android.com/training/articles/memory.html
UPDATE
After working excrutiatingly with out of memory errors i would say adding this to the manifest to avoid the oom issue is not a sin, also like #Milad points out below it does not affect the normal working of the app
UPDATE 2
Here are a few tips to deal with out of memory errors
1) Use these callback that android gives onLowMemory, onTrimMemory(int) and clear the cache of image like (picasso, glide, fresco....) you can read more about them here and here
2) compress your files(images, pdf)
3) read about how to handle bitmap more efficiently here
4) Use lint regularly before production pushes to ensure code is sleek and
not bulky
I think this is a very effective question, and let me add some details about advantages and disadvantages of using this option.
What You Get :
Obviously, you get larger heap, which means decreasing risk of OutOfMemoryError.
What You Lose :
You may lose some frames, which can cause a visible hitching. Larger heap makes garbage collections take longer. Because the garbage collector basically has to traverse your entire live set of objects. Usually, garbage collection pause time is about 5ms, and you may think few milliseconds are not a big deal. But every millisecond count. Android device has to update its screen in every 16 ms and longer GC time might push your frame processing time over the 16 millisecond barrier, which can cause a visible hitching.
Also switching apps will become slower. Android system may kill processes in the LRU cache beginning with the process least recently used, but also giving some consideration toward which processes are most memory intensive. So if you use larger heap, your process would more likely to be killed when it's backgrounded, which means it may take longer time when users want to switch from other apps to yours. Also other backgrounded processes will more likely to be kicked out when your process is foreground, because your app require larger memory. It means switching from your app to other apps also takes longer.
Conclusion :
Avoid using largeHeap option as much as possible. It may cost you hard-to-notice performance drop and bad user experience.
If you must use (and retain) a large amount of memory, then yes, you can and should use android:largeHeap="true". But if you do use it, you should be prepared to have your app flushed from memory whenever other apps are in the foreground.
By "be prepared," I mean that you should design for that likelihood, so that your onStop() and onResume() methods are written as efficiently as possible, while ensuring that all pertinent state is saved and restored in a manner that presents a seamless appearance to the user.
There are three methods that relate to this parameter: maxMemory(), getMemoryClass(), and getLargeMemoryClass().
For most devices, maxMemory() will represent a similar value to getMemoryClass() by default, although the latter is expressed in megabytes, while the former is expressed in bytes.
When you use the largeHeap parameter, maxMemory() will be increased to a device-specific higher level, while getMemoryClass() will remain the same.
getMemoryClass() does not constrain your heap size, but it tells you the amount of heap you should use if you want your app to function comfortably and compatibly within the limits of the particular device on which you are running.
maxMemory(), by contrast, does constrain your heap size, and so you do gain access to additional heap through increasing its value, and largeHeap does increase that value. However, the increased amount of heap is still limited, and that limit will be device-specific, which means that the amount of heap available to your app will vary, depending on the resources of the device on which your app is running. So, using largeHeap is not an invitation for your app to abandon all caution and oink its way through the all-you-can-eat buffet.
Your app can discover exactly how much memory would be made available on a particular device through using the largeHeap parameter by invoking the method getLargeMemoryClass(). The value returned is in megabytes.
This earlier post includes a discussion of the largeHeap parameter, as well as a number of examples of what amounts of heap are made available with and without its usage, on several specific Android devices:
Detect application heap size in Android
I have not deployed any of my own apps with this parameter set to true. However, I have some memory-intensive code in one of my apps for compiling a set of optimization-related parameters, that runs only during development. I add the largeHeap parameter only during development, in order to avoid out of memory errors while running this code. But I remove the parameter (and the code) prior to deploying the app.
Actually android:largeHeap is the instrument for increasing your allocated memory to app.
There is no clear definition of the need to use this flag. If you need more memory - Android provides you with a tool to increase it. But necessity of using, you define yourself.
I have an App with almost 50 classes
I don't think this makes much problem. The reason why you've got outOfMemory error is usually loading too much images in your app or something like that. If you are unhappy to use large heap you must find a way to optimize using memory.
You can also use Image Loading Libraries such as Picasso, UIL or Glide. All of them have the feature of image caching in memory and/or on disk.
Whether your application's processes should be created with a large Dalvik heap. This applies to all processes created for the application. It only applies to the first application loaded into a process; if you're using a shared user ID to allow multiple applications to use a process, they all must use this option consistently or they will have unpredictable results.
Most apps should not need this and should instead focus on reducing their overall memory usage for improved performance. Enabling this also does not guarantee a fixed increase in available memory, because some devices are constrained by their total available memory.

Two questions about max heap sizes and available memory in android

I see that the Heap Size is automatically increased as the app needs it, up to whatever the phone's Max Heap Size is. I also see that the Max Heap Size is different depending on the device.
So my first question is, what are the typical Max Heap Sizes on Android devices? I have tested memory allocation on one phone that was able to use a heap over 40mb while another gave out OutOfMemory errors in the 20's mbs. What are the lowest that are in common use and what are the highest that are on common devices? Is there a standard or average?
The second question, and more important one, is how to ensure you are able to use the resources available per device but avoid using too much? I know there are methods such as onLowMemory() but those seem to be only for the entire system memory, not just the heap for your specific application.
Is there a way to detect the max heap size for the device and also detect when the available heap memory is reaching a low point for your application?
For example, if the device only allowed a max heap of 24mb and the app was nearing that limit in allocation, then it could detect and scale back. However, if the device could comfortably handle more, it would be able to take advantage of what is available.
Thanks
Early devices had a per-app cap of 16MB. Later devices increased that to 24MB. Future devices will likely have even more available.
The value is a reflection of the physical memory available on the device and the properties of the display device (because a larger screen capable of displaying more colors will usually require larger bitmaps).
Edit: Additional musings...
I read an article not too long ago that pointed out that garbage-collecting allocators are essentially modeling a machine with infinite memory. You can allocate as much as you want and it'll take care of the details. Android mostly works this way; you keep hard references to the stuff you need, soft/weak references to stuff you might not, and discard references to the stuff you'll never need again. The GC sorts it all out.
In your particular case, you'd use soft references to keep around the things that you don't need to have in memory, but would like to keep if there's enough room.
This starts to fall apart with bitmaps, largely because of some early design decisions that resulted in the "external allocation" mechanism. Further, the soft reference mechanism needs some tuning -- the initial version tended to either keep everything or discard everything.
The Dalvik heap is under active development (see e.g. the notes on Android 2.3 "Gingerbread", which introduces a concurrent GC), so hopefully these issues will be addressed in a future release.
Edit: Update...
The "external allocation" mechanism went away in 4.0 (Ice Cream Sandwich). The pixel data for Bitmaps is now stored on the Dalvik heap, avoiding the earlier annoyances.
Recent devices (e.g. the Nexus 4) cap the heap size at 96MB or more.
A general sense of the app's memory limits can be obtained as the "memory class", from ActivityManager.getMemoryClass(). A more specific value can be had from the java.lang.Runtime function maxMemory().
Here are the "normal" (see below) heap sizes for some specific devices:
G1: 16MB
Moto Droid: 24MB
Nexus One: 32MB
Viewsonic GTab: 32MB
Novo7 Paladin: 60MB
I say "normal" because some versions of Android (e.g., CyanogenMod) will allow a user to manually adjust the heap limit. The result can be larger or smaller than the "normal" values.
See this answer for additional information, including how to find out what the heap size actually is programmatically, and also how to distinguish between the absolute heap size limit on the one hand and the heap limit that you should ideally respect, on the other:
Detect application heap size in Android
To detect what your present heap utilization is, you could try using the Runtime class' totalMemory() method. However, I've read reports that different versions/implementations of the Android OS may have different policies regarding whether native memory (from which the backing memory for bitmaps is allocated) is counted against the heap's maximum or not. And, since version 3.0, the native memory is directly taken from the application's own heap.
The iffiness of this calculation makes me think that it is a mistake to monitor your app's usage of memory at runtime, constantly comparing it to the amount available. Also, if you are in the middle of an involved computation, and find that you're running out of memory, it is not always convenient or reasonable to cancel that computation, and it may create a bad experience for your users if you do.
Instead, you might try preemptively defining certain modes, or constraints, upon your app's functional behavior that will ensure that it comes in under whatever your current device's relevant heap limits are (as detected during your app's initialization).
For example, if you have an app that uses a large list of words that must be loaded into memory all at once, then you might constrain your app so that for smaller heap limits only a smaller list of the more common words can be loaded, while for larger heap limits a full list containing many more words can be loaded.
There are also Java programming techniques that allow you to declare certain memory to be reclaimable by the garbage collector on demand, even if it has existing "soft" (rather than hard) references. If you have data that you would like to keep in memory, but which can be re-loaded from non-volatile storage if required (i.e., a cache), then you might consider using soft references to have such memory automatically freed when your app starts bumping against the upper limits of your heap. See this page for info on soft references in Android:
http://developer.android.com/reference/java/lang/ref/SoftReference.html

Is using largeheap in Android manifest a good practice?

I am developing in NDK. It hangs in Galaxy S3. For testing I put android:largeheap = "true" in Manifest. Then there was no hanging issue.
Is it a good practice to use largeHeap="true"?
Is there any chance that Google rejects my build due to this tag and
how can I prevent my app from hanging without using largeheap="true"?
Short Answer
No, if you need it it is not a bad pactise because it is there for it.
Long Answer
Official doc states
Whether your application's processes should be created with a large
Dalvik heap. This applies to all processes created for the
application. It only applies to the first application loaded into a
process; if you're using a shared user ID to allow multiple
applications to use a process, they all must use this option
consistently or they will have unpredictable results. Most apps should
not need this and should instead focus on reducing their overall
memory usage for improved performance. Enabling this also does not
guarantee a fixed increase in available memory, because some devices
are constrained by their total available memory.
Some developers uses it to avoid OOM excepetion, so if you are using it just to avoid some OOM it is a very very bad pactice.
Never request a large heap simply because you've run out of memory and
you need a quick fix. You should use it only when you know exactly
where all your memory is being allocated and why it must be retained
If you actually need more space it's ok to use it, you can use getMemoryClass() to check the heap and getLargeMemoryClass() large heap.
But if you can avoid using the largeHeap it would be the best way to go, as the official documentation continues:
Yet, even when you're confident your app can justify the large heap,
you should avoid requesting it to whatever extent possible. Using the
extra memory will increasingly be to the detriment of the overall user
experience because garbage collection will take longer and system
performance may be slower when task switching or performing other
common operations. Additionally, the large heap size is not the
same on all devices and may be exactly the same as the regular heap
size. So even if you do request the large heap size, you should call
getMemoryClass() to check the regular heap size and strive to always
stay below that limit.
I also suggest you to have a look here Managing Your App's Memory
Personally I would say it doesn't really fall into the category of either 'good/bad practice' when used correctly.
According to the docs:
Most apps should not need this and should instead focus on reducing
their overall memory usage for improved performance. Enabling this
also does not guarantee a fixed increase in available memory, because
some devices are constrained by their total available memory.
If you have done everything in your power to reduce memory usage, and still require it, then it isn't a bad thing to use it.
If your app is hanging, you will need to directly address that - the largeHeap isn't a magic wand that will make problems go away for all devices. This point is made clear from the following extract of the Android Training docs:
[The] ability to request a large heap is intended only for a
small set of apps that can justify the need to consume more RAM (such
as a large photo editing app). Never request a large heap simply
because you've run out of memory and you need a quick fix—you should
use it only when you know exactly where all your memory is being
allocated and why it must be retained. - (source)
I should also add that Google will not reject your app for using it.

Categories

Resources