/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.imagepipeline.memory;
import android.util.SparseIntArray;
import com.facebook.common.util.ByteConstants;
/**
* Provides pool parameters ({@link PoolParams}) for {@link NativeMemoryChunkPool}
*
*/
public class DefaultNativeMemoryChunkPoolParams {
/**
* Length of 'small' sized buckets. Bucket lengths for these buckets are larger because
* they're smaller in size
*/
private static final int SMALL_BUCKET_LENGTH = 5;
/**
* Bucket lengths for 'large' (> 256KB) buckets
*/
private static final int LARGE_BUCKET_LENGTH = 2;
public static PoolParams get() {
SparseIntArray DEFAULT_BUCKETS = new SparseIntArray();
DEFAULT_BUCKETS.put(1 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(2 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(4 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(8 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(16 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(32 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(64 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(128 * ByteConstants.KB, SMALL_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(256 * ByteConstants.KB, LARGE_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(512 * ByteConstants.KB, LARGE_BUCKET_LENGTH);
DEFAULT_BUCKETS.put(1024 * ByteConstants.KB, LARGE_BUCKET_LENGTH);
return new PoolParams(
getMaxSizeSoftCap(),
getMaxSizeHardCap(),
DEFAULT_BUCKETS);
}
/**
* {@link NativeMemoryChunkPool} manages memory on the native heap, so we don't need as strict
* caps as we would if we were on the Dalvik heap. However, since native memory OOMs are
* significantly more problematic than Dalvik OOMs, we would like to stay conservative.
*/
private static int getMaxSizeSoftCap() {
final int maxMemory = (int)Math.min(Runtime.getRuntime().maxMemory(), Integer.MAX_VALUE);
if (maxMemory < 16 * ByteConstants.MB) {
return 3 * ByteConstants.MB;
} else if (maxMemory < 32 * ByteConstants.MB) {
return 6 * ByteConstants.MB;
} else {
return 12 * ByteConstants.MB;
}
}
/**
* We need a smaller cap for devices with less then 16 MB so that we don't run the risk of
* evicting other processes from the native heap.
*/
private static int getMaxSizeHardCap() {
final int maxMemory = (int) Math.min(Runtime.getRuntime().maxMemory(), Integer.MAX_VALUE);
if (maxMemory < 16 * ByteConstants.MB) {
return maxMemory / 2;
} else {
return maxMemory / 4 * 3;
}
}
}