M
M
MikkiMouse2016-03-18 12:07:57
Android
MikkiMouse, 2016-03-18 12:07:57

Is there a memory leak?

Good afternoon, the situation is this:
There is a service, it downloads images from the server and saves them to the cache. Images are about 400Kb, but the memory eats up 10-15 times more. Tell me, am I downloading and saving them correctly?
In the service code, I download in the downloadImages method, get the names of the images, check if the image has already been downloaded, if not, then download and save:

...
private boolean downloadImages() {
...
  String[] imageNames = data[0].split("\\s*" + Config.DATA_IMAGE_NAMES_SEP + "\\s*");
  for(String imgName : imageNames) {
    if(CacheManager.getInstance(this).getImage(imgName) == null) {
      Bitmap image = getBitmap(Config.SERVER_URL + imgName);

      CacheManager.getInstance(this).saveImage(imgName, image);
    }
  }
...
}

private Bitmap getBitmap(String aUrl) throws IOException {
  try {
    byte[] bitmapBytes = getUrlBytes(aUrl);
    return BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
  } catch (IOException ioe) {
    return null;
  }
}

private byte[] getUrlBytes(String aUrl) throws IOException {
  final HttpParams httpParams = new BasicHttpParams();
  HttpClient client = new DefaultHttpClient(httpParams);
  HttpGet request = new HttpGet(aUrl);
  request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0");
  request.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
  request.setHeader("Accept-Language", "ru,en-us;q=0.7,en;q=0.3");
  request.setHeader("Accept-Charset", "windows-1251,utf-8;q=0.7,*;q=0.7");

  HttpResponse response = client.execute(request);

  ByteArrayOutputStream out = new ByteArrayOutputStream();
  InputStream in = response.getEntity().getContent();
  int bytesRead = 0;
  byte[] buffer = new byte[1024];
  while ((bytesRead = in.read(buffer)) > 0) {
    out.write(buffer, 0, bytesRead);
  }
  out.close();

  return out.toByteArray();
}

The resulting image is saved to the cache in the saveImage method:
private CacheManager(Context context) {
  mContext = context;

  mLRU = new LruCache<Object, Object>(1024);
  loadImagesFromCacheToLRU();
}

public void saveImage(String aName, Bitmap aImage) {
  String filePath = mContext.getCacheDir().getAbsolutePath() + "/" + RESOURCE_IMAGES_PREFIX + aName;

  File file = new File(filePath);
  if(!file.exists()) {
    try {
      FileOutputStream fos = new FileOutputStream(filePath);
      aImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);
      fos.flush();
      fos.close();
    } catch (IOException e) {
      Log.e(TAG, "Cannot save image to cache! " + e.getMessage());
    }
  }

  mLRU.put(aName, aImage);
}

public Bitmap getImage(String aName) {
  return (Bitmap) mLRU.get(aName);
}

Is everything correct in these pieces of code?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
T
Tiberal, 2016-03-18
@MikkiMouse

The problem is in the cycle (and not one)! You are storing too many bitmaps in memory!
Each time it creates a new object and keeps it in memory, and it is not known when these objects will be deleted by the collector, so you catch OOM. You need to access Bitmap via SoftReference. In this case, when the memory is very bad, gc will release the resources wrapped in SoftReference.
Well, it would not hurt to pull recycle () on the Bitmap when it is not needed.
You should not do this either, strings, like bitmaps, are immutable, and a new object will be created at each iteration. Use a string builder.

D
Denis Zagaevsky, 2016-03-18
@zagayevskiy

They gave you these bikes. Use Picasso or Glide to upload images.
As for memory, try profiling the application. And how did you understand that the memory eats up more than necessary?
Regarding lru cache - it seems that you are using it incorrectly. He himself will not correctly calculate the size of the bitmap. In the docks, this is normally parsed: developer.android.com/intl/ru/reference/android/ut...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question