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