public static long GetTotalMemory(bool forceFullCollection) {
long size = nativeGetTotalMemory();
if (!forceFullCollection)
return size;
// If we force a full collection, we will run the finalizers on all
// existing objects and do a collection until the value stabilizes.
// The value is "stable" when either the value is within 5% of the
// previous call to nativeGetTotalMemory, or if we have been sitting
// here for more than x times (we don't want to loop forever here).
int reps = 20; // Number of iterations
long newSize = size;
float diff;
do {
GC.WaitForPendingFinalizers();
GC.Collect();
size = newSize;
newSize = nativeGetTotalMemory();
diff = ((float)(newSize - size)) / size;
} while (reps-- > 0 && !(-.05 < diff && diff < .05));
return newSize;
}