У меня происходит утечка памяти в моем приложении, которое запускает GC несколько раз и вызывает проблемы с производительностью. Я создал leak suspect report
, используя MAT
. Вот отчет:Bitmap Memory leak - Android
Проблема Подозреваемый 1: Один экземпляр "android.graphics.Bitmap" загружен "" занимает 4,194,368 (20,13%) байт. Память накапливается в одном экземпляре «byte []», загружаемом «».
Проблема Подозреваемый 2: Класс "android.content.res.Resources", нагружен "", занимает 3,962,504 (19,02%) байт. Память накапливается в одном экземпляре «java.lang.Object []», загруженного «».
Задача Подозреваемый 3: Один экземпляр "android.graphics.Bitmap" загружен "" занимает 3,145,792 (15,10%) байт. Память накапливается в одном экземпляре «byte []», загружаемом «».
Судя по сообщениям, очевидно, что утечка памяти происходит из-за растрового изображения. Я много исследовал, но не смог исправить эту утечку. Пожалуйста, помогите мне. Я использую класс ImageLoader
для загрузки и отображения растровых изображений. Чтобы использовать этот класс, я просто вызываю метод displayImage()
. Вот код:
public class ImageLoader {
private static ImageLoader imageLoader;
private int maxNoOfConnections = 4;
FileCache fileCache;
ExecutorService executorService;
HttpURLConnection conn;
InputStream is;
OutputStream os;
PhotosLoader photosLoader;
Handler handler;
Bitmap bitmap;
private ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(maxNoOfConnections);
handler = new Handler();
}
public static ImageLoader getInstance(Context context) {
if (imageLoader == null)
imageLoader = new ImageLoader(context);
return imageLoader;
}
public void displayImage(String url, ProgressBar pBar, ImageView imageView) {
photosLoader = new PhotosLoader(url, imageView, pBar);
executorService.submit(photosLoader);
}
private Bitmap getBitmap(String url) {
File f = fileCache.getFile(url);
bitmap = decodeFile(f);
if (bitmap != null)
return bitmap;
try
{
URL imageUrl = new URL(url);
conn = (HttpURLConnection) imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
is = conn.getInputStream();
os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
} catch (Exception ex)
{
Log.e("inNews", "Image Url Malformed");
return null;
}
}
private Bitmap decodeFile(File f) {
try
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp/2 < REQUIRED_SIZE || height_tmp/2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e)
{
}
return null;
}
class PhotosLoader implements Runnable {
String url;
ImageView imageView;
ProgressBar pBar;
Bitmap bmp;
public PhotosLoader(String url, ImageView imageView, ProgressBar pBar) {
this.url = url;
this.imageView = imageView;
this.pBar = pBar;
}
@Override
public void run() {
bmp = getBitmap(url);
handler.post(new Runnable() {
@Override
public void run() {
if (bmp != null)
{
pBar.setVisibility(View.GONE);
imageView.setImageBitmap(bmp);
} else
{
pBar.setVisibility(View.GONE);
imageView.setImageResource(R.drawable.img_no_image_grid);
}
}
});
}
}
}
Пожалуйста, помогите мне исправить свой код. Благодаря!
Примечание: Я не использовал bitmap.recycle()
с тех пор, в документации сказано, что после Honeycomb ГХ собирает растровые изображения и его больше нет необходимости, чтобы принудительно утилизировать его!
Вы получаете утечку памяти в случайное время, всегда в то же время, когда вы вращаете устройство ...? – Fustigador
Вы должны прочитать о SoftReference в Android doc, в вашем случае, если вы где-нибудь сохранили возвращаемый Bitmap, он останется в памяти –
@Fustigador всякий раз, когда я делаю какие-либо действия, связанные с загрузкой изображений. Не специально вращать устройство. – gauravsapiens