views:

197

answers:

1

The NDK download page notes that, "Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't allocate much memory, such as signal processing, physics simulation, and so on."

I came from a C background and was excited to try to use the NDK to operate most of my OpenGL ES functions and any native functions related to physics, animation of vertices, etc... I'm finding that I'm relying quite a bit on Native code and wondering if I may be making some mistakes. I've had no trouble with testing at this point, but I'm curious if I may run into problems in the future.

For example, I have game struct defined (somewhat like is seen in the San-Angeles example). I'm loading vertex information for objects dynamically (just what is needed for an active game area) so there's quite a bit of memory allocation happening for vertices, normals, texture coordinates, indices and texture graphic data... just to name the essentials. I'm quite careful about freeing what is allocated between game areas.

Would I be safer setting some caps on array sizes or should I charge bravely forward as I'm going now?

+1  A: 

Since applications using the NDK should behave similarly to those developed using the SDK, I think the best guidance for reasonable heap usage comes from the comments of ActivityManager.java.

/**
 * Return the approximate per-application memory class of the current
 * device.  This gives you an idea of how hard a memory limit you should
 * impose on your application to let the overall system work best.  The
 * returned value is in megabytes; the baseline Android memory class is
 * 16 (which happens to be the Java heap limit of those devices); some
 * device with more memory may return 24 or even higher numbers.
 */
public int getMemoryClass() {
    return staticGetMemoryClass();
}

/** @hide */
static public int staticGetMemoryClass() {
    // Really brain dead right now -- just take this from the configured
    // vm heap size, and assume it is in megabytes and thus ends with "m".
    String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
    return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
}

The code that sets the heap size for the Dalvik VM is in AndroidRuntime.cpp and provides an example for how to determine a rough limit for heap allocations in native code using the property_get function.

strcpy(heapsizeOptsBuf, "-Xmx");
property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
//LOGI("Heap size: %s", heapsizeOptsBuf);
opt.optionString = heapsizeOptsBuf;
mOptions.add(opt);

The default value of 16m is likely important as neither of the two Android phones I own have the dalvik.vm.heapsize property set by default.

Tim Kryger
Thanks Tim. That's a little scary staying under 16MB. If I understand this right, it's a cap that can be implemented by the phone manufacturer build of the OS so that each application can only access a certain amount of memory? If that cap isn't set, then can each application can allocate as much from available RAM (within reason of course) as it needs? Are you saying when getMemoryClass() is ran on your phones they return null? Which phones do you have, if I may be so bold to ask... Is there anywhere that might have information on this limit for newer phones? (Am I completely off base?)
Maximus
Maximus
@Maximus Dianne's comments sum it up extremely well. While there isn't a hard limit on how much heap can be allocated with the NDK (running `ulimit -d` returns `unlimited`), there are consequences to using all the available memory.
Tim Kryger